home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-09 | 150.9 KB | 3,735 lines |
- ********************************************************************************
- *
- * Project name : NORMALIZED KEY CODE CONVERTER (NKCC)
- * Module name : Main module
- * Symbol prefix: nkc
- *
- * Author : Harald Siegmund (HS)
- * Co-Authors : -
- * Write access : HS
- *
- * Notes : The symbol NKCGEM will have to be defined on the assembler's
- * command line when translating the source of NKCC. Set its
- * value to 1 if you like to create the complete version. A value
- * of 0 will supress inclusion of the GEM part, making NKCC a few
- * KBytes smaller. Some functions and the GEM parameter arrays
- * are not available then.
- *
- * Translate this source with the Pure assembler:
- * pasm [-B] -DNKCGEM=1 -Onkcc.o nkcc.s
- * pasm [-B] -DNKCGEM=0 -Onkcc_tos.o nkcc.s
- *
- * WARNING: Old versions of the Pure assemblers have serious
- * bugs! Version Jun 21 1993 works fine.
- *
- *-------------------------------------------------------------------------------
- *END
- * Things to do :
- *
- * - NKCC will support additional (and more complex) deadkeys some time, such
- * like Arabian ones. A communication interface between NKCC and a text
- * editor will be built in for that purpose (Arabian languages' deadkeys can
- * affect existing text!).
- *
- *-------------------------------------------------------------------------------
- * History:
- *
- * 1989:
- * May 14: creation of file (NKCC 1.00)
- * Jun 07/15-16/19/21/Jul 11: improvements, changes, debugging
- * 1990:
- * Jan 13: global functions now available in two versions:
- * parameters passed via registers (e.g. for Turbo C)
- * parameters passed via stack (underscore before label name)
- *
- * May 23-24/26-28: creation of NKCC 2.00 (almost every function rewritten)
- * Jun 16/27: assembler-entry added by Gerd Knops
- * Jun 30/Jul 02: return shift key flags in nkc_multi()/amulti() as NKF?_...
- * Jul 09: nkc_kstate()
- * Aug 03: nkc_cmp()
- * Aug 18: fatal bug in nkc_kstate() fixed
- * Sep 15: nkc_timer()
- * Sep 15-17/30: own button event handler
- * Oct 03: debugging
- * nkc_vlink()/vunlink()
- * documentation syntax changed (LRef/XRef removed; Reg: changed)
- * Oct 05: debugging mouse button handler (problems with menu bar)
- * Oct 07: Control/Alternate + character always returns capital characters
- * changing key code comparism rules in nkc_cmp()
- * Oct 22: debugging nkc_cmp() (did sometimes recognize unique key codes)
- * debugging ASCII code input in nkc_amulti()
- * Dec 11/15/17: MU_XTIMER
- * 1991:
- * Jan 11: don't call AES with set MU_XTIMER flag
- * Mar 31: ensure that evnt_multi() parameters are restored when being
- * corrupted by a bug in AES!!
- * Apr 01: debugging
- * Apr 13: nkc_conv() renamed to nkc_tconv()
- * Apr 13-14: nkc_gconv()
- * May 10: debugging (nk_beend())
- * May 29: debugging (double shift key compare)
- * export nkc_toupper and nkc_tolower
- * Jul 05: completing history
- * Jul 31: version number before XBRA header
- * Aug 06: " is now a deadkey!
- * Aug 07: more deadkeys...
- * Aug 22: deadkeys can now be enabled/disabled separately
- * nkc_set() changed
- * nkc_init() returns version #
- * bug fixed: nkc_cmp() corrupted high words of D3 and D4
- * Sep 07/14: nkc_cmp() improved; NKF?_RESVD now in use
- * Nov 05: adjustments to ASCII input feature of TOS 3.06
- * Nov 16: bug fixed in nkc_cmp() mechanism
- * Control key emulation
- * Dec 29: small corrections and extensions of the documentation
- * source documentation syntax now in extra file
- * 1992:
- * Jan 03: changing documentation of nkc_init()
- * revising info lines in function headers
- * Jan 12: adjusting nkc_init() to its new documentation!
- * appending .b respectively .l to all instructions with a default
- * operand size which is not .w
- * changing macro XBRA_HD
- * Feb 11: adjusting button event handler to MINT
- * Feb 28: NKCOWNPB switch
- * 1993:
- * Dec 11: merging the two existing NKCC versions to one source:
- * - version number set to $0290
- * - NKCNOGEM/NKCOWNPB keys replaced by NKCGEM key
- * - NKCC uses its own AES/VDI parameter arrays now
- * - nkc_init() gets one more parameter: ^AES global array
- * - nkc_toupper and nkc_tolower are functions now
- * - dynamic double click time
- * - MU_MESAG occured -> don't create self-made button events
- * Dec 12: GEM keyboard events: try to get original shift flags from the
- * Iorec buffer
- * new functions: nkc_n2tos() and nkc_n2gem()
- * Dec 13: debugging: ! operator changed to ~ in nk_bestart
- * implementing nkc_n2tos()
- * size of GEM parameter arrays changed to 32 (larger than required
- * but better too big than too small!)
- * Dec 16: debugging nkc_n2tos()
- * Dec 19: improving nkc_gconv() (scan code translation table)
- * debugging nkc_n2tos()
- * cosmetic changes
- * Dec 23: debugging nkc_vunlink(): return status was garbage!
- * 1994:
- * May 19: release 2.91:
- * don't restore conterm (it may be changed by another process in
- * the meantime)
- * new deadkeys (/2 /4)
- * adding overview of used MadMac directives in the note section of
- * the file header
- * Jun 27: release 2.92:
- * check for illegal scan codes (e.g. $ff under Mag!x)
- * Oct 31: adding C prototypes to headers of public functions
- * 1995:
- * Nov 06: source adjusted for translation with Pure assembler
- * Nov 09: release 2.93:
- * the additional keys on the Macintosh keyboard are supported now
- *
- ********************************************************************************
- *KEY _NAME="NKCC"
-
- *START
- ****************************************************************************
- * ASSEMBLER CONTROL SECTION *
- ****************************************************************************
-
- *KEY &NKCGEM
- * define this symbol on the assembler's command line
- * =0 create TOS-version of NKCC (without GEM part)
- * =1 create GEM-version of NKCC
-
- .include "nkcc.i" ; NKCC definitions
- *END
- *KEY _END
-
-
-
- *START
- ****************************************************************************
- * EXPORT *
- ****************************************************************************
-
- ; functions
- .globl nkc_init ; init NKCC
- .globl nkc_exit ; exit NKCC
- .globl nkc_set ; set special key flags
- .globl nkc_conin ; NKCC key input via GEMDOS
- .globl nkc_cstat ; console input status via GEMDOS
- .globl nkc_tconv ; TOS key code converter
- .globl nkc_gconv ; GEM key code converter
- .globl nkc_n2tos ; NKC to TOS key code converter
- .globl nkc_n2gem ; NKC to GEM key code converter
- .globl nkc_kstate ; return shift key state
- .globl nkc_timer ; return 200 Hz system clock
- .globl nkc_cmp ; compare two key codes
- .globl nkc_vlink ; link function to XBRA vector list
- .globl nkc_vunlink ; unlink function from XBRA list
- .globl nkc_toupper ; convert character to upper case
- .globl nkc_tolower ; convert character to lower case
-
- .if NKCGEM=1
-
- .globl nkc_multi ; NKCC multi event handler
- .globl nkc_amulti ; multi event, assembler binding
- .globl nkc_contrl ; GEM parameter arrays
- .globl nkc_intin
- .globl nkc_intout
- .globl nkc_adrin
- .globl nkc_adrout
- .globl nkc_ptsin
- .globl nkc_ptsout
-
- .endif ; .if NKCGEM=1
- *END
-
-
-
- ****************************************************************************
- * EQUATES *
- ****************************************************************************
-
- VERSION = $0293 ; NKCC's version #
-
- ; AES event mask bits
- MU_KEYBD = $0001 ; keyboard
- MU_BUTTON = $0002 ; mouse button clicks
- MU_M1 = $0004 ; mouse movement #1
- MU_M2 = $0008 ; mouse movement #2
- MU_MESAG = $0010 ; message
- MU_TIMER = $0020 ; timer
-
- conterm = $484 ; .B: system key flags
- _hz_200 = $4ba ; .L: 200 Hz system clock
- _sysbase = $4f2 ; .L: ^OS header
-
- TIME_ADD = 20 ; wait time to add on each click
- ; in 1/200 s (-> 100 ms)
-
-
- ****************************************************************************
- * ABSOLUTE SECTION *
- ****************************************************************************
-
- .offset ; button event info block
-
- BI_BSTATE: .ds.w 1 ; requested button state
- BI_BMASK: .ds.w 1 ; requested button mask
- BI_REVCOND: .ds.w 1 ; event condition reverse flag
- BI_MAXCLICKS: .ds.w 1 ; max # of clicks to wait for
- BI_DCLTIME: .ds.w 1 ; AES double click time
- BI_BMODE: .ds.w 1 ; button handler mode (see
- ; function nk_butvec)
- BI_SBSTATE: .ds.w 1 ; button state at start of event
- BI_PRVBSTATE: .ds.w 1 ; previous button state
- BI_NCLICKS: .ds.w 1 ; # of mouse clicks
- BI_DCBUT: .ds.w 1 ; double click button mask
- BI_DCSTATE: .ds.w 1 ; double click button state
- BI_BENDTIME: .ds.l 1 ; button event timer end value
- BI_BEVALID: .ds.b 1 ; flag: button event valid
- BI_CVALID: .ds.b 1 ; flag: button condition valid
- BI_LOCK: .ds.b 1 ; flag: button event locked
- .even
- BI: ; size
-
-
- .offset ; IOREC structure
-
- IBUF: .ds.l 1 ; ^base of I/O buffer
- IBUFSIZ: .ds.w 1 ; size of buffer in bytes
- IBUFHD: .ds.w 1 ; head-pointer (offset to last
- ; used read position
- IBUFTL: .ds.w 1 ; tail-pointer (offset to last
- ; used write position
- IBUFLO: .ds.w 1 ; low water mark
- IBUFHI: .ds.w 1 ; high water mark
- IOREC: ; size
-
-
-
- ****************************************************************************
- * MACROS *
- ****************************************************************************
-
- ****************************************************************************
- *
- * LWDIVU: divide long value <da> by word value <db>, use <dt> for temp storage
- *
- * - the result will be stored as LONGword in <da>
- * - <db> stays unchanged
- * - <da> and <dt> must be data registers
- *
- ****************************************************************************
-
- .macro LWDIVU db,da,dt
-
- move.l &da,&dt ; copy long-value
- clr &dt ; clear its low word
- swap &dt ; dt.w = high word of long-value
- divu &db,&dt ; high word / word-value
- swap &da ; long-value, low and high swapped
- move &dt,&da ; da.w = result of high/word-value
- swap &da ; da.w = low word of long-value
- move &da,&dt ; remainder and low-word
- divu &db,&dt ; divide by word-value
- move &dt,&da ; so we get low word of result
-
- .endm
-
-
-
- ****************************************************************************
- *
- * XBRA_HD: XBRA header for NKCC functions
- *
- * The following structure is stored at the current memory location:
- *
- * VERSION.L NKCC's version # (actually not a part of a standard XBRA
- * header; may be checked in future versions)
- * "XBRA".L magic longword
- * "NKCC".L NKCC's XBRA-ID
- * oldvec.L initial value of buffer for old vector content (passed as
- * macro parameter); usually 0
- *
- ****************************************************************************
-
- .macro XBRA_HD oldvec
-
- .dc.l VERSION ; version number
- .dc.b "XBRA" ; XBRA header
- .dc.b "NKCC" ; ID
- .dc.l &oldvec ; chain pointer to next routine
-
- .endm
-
-
-
- ****************************************************************************
- * LOCAL TEXT SECTION *
- ****************************************************************************
-
- .text
-
- ****************************************************************************
- *
- * nk_gci: GEMDOS console character input
- * #
- *
- * This function returns when
- *
- * a) either any key is pressed or
- * b) the Alternate key is released
- *
- * The Alternate check can be suppressed by setting the input parameter in
- * D0.W to zero. The routine works then just as a "get key" function.
- *
- * In: D0.W Alternate key check flag:
- * zero = don't check it
- * non-zero = do Alternate check
- *
- * Out: D0.W key code in normalized format
- * for details see nkc_tconv()
- * D1.W flag:
- * zero = D0.W not valid; Alternate was released
- * non-zero = D1.W valid; Alternate still pressed
- * (also returned when Alternate check supressed)
- * CCR set according content of D1.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U***.... ****.... =D1.W
- *
- ****************************************************************************
-
- nk_gci: move d0,d3 ; Alternate check flag
- beq.s .getkey ; no check? just get key
-
- move.l pshift,a3 ; ^shift key state
-
- .loop: btst.b #3,(a3) ; Alternate still pressed?
- beq.s .abort ; no->
-
- move #11,-(sp) ; Cconis: get key input status
- trap #1 ; Gemdos
- addq #2,sp ; clean stack
-
- tst d0 ; any key pressed?
- beq.s .loop ; no->
-
- .getkey: move #7,-(sp) ; Crawcin: get key
- trap #1 ; Gemdos
- addq #2,sp ; clean stack
- bsr nkc_tconv ; convert key code
- moveq.l #-1,d1 ; flag: key code valid
- rts ; bye
-
- .abort: moveq.l #0,d1 ; flag: key code not valid
- rts ; bye
-
-
-
- ****************************************************************************
- *
- * nk_spec: special key code handling
- * #
- *
- * nk_spec() performs the special key handling defined by <sflags> (deadkey
- * management, ASCII code input, Control key emulation).
- *
- * In: D0.W key code in normalized format
- * for details see nkc_tconv()
- * A0.L ^function which gets new key codes and checks
- * the Alternate key state
- * For the calling conventions consult nk_gci() or
- * nk_mci(). The function MUST NOT modify the CPU
- * registers D5-D7 and A5-A6.
- *
- * Out: D0.W (new) key code in normalized format
- * CCR set according contents of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U******* *******. =D0.W
- *
- ****************************************************************************
-
- nk_spec: move.l a0,a6 ; save ^function
- btst.b #NKSb_ALTNUM,sflags + 3 ; ASCII input enabled?
- beq.s .ctrlkey ; no->
-
-
- *------------- ASCII input
-
- moveq.l #0,d6 ; reset digit counter
- moveq.l #0,d5 ; reset ASCII code
- bra.s .isdigit ; check if valid key
-
- .notvalid: tst d6 ; key not valid; first one?
- beq.s .ctrlkey ; yes-> exit
-
- .getkey: move d0,d7 ; save previous key code
- moveq.l #-1,d0 ; check Alternate
- jsr (a6) ; get key
- beq.s .makeascii ; Alternate released? abort loop
-
- .isdigit: move d0,d1 ; key code
- and #NKFf_NUM | NKFf_ALT,d1 ; isolate flags
- cmp #NKFf_NUM | NKFf_ALT,d1 ; with Alternate and numeric?
- bne.s .notvalid ; no->
-
- cmp.b #'0',d0 ; must be in range from 0 ...
- blo.s .notvalid
-
- cmp.b #'9',d0 ; ... to 9
- bhi.s .notvalid
-
- mulu #10,d5 ; new digit in ASCII code
- sub #'0',d0 ; ASCII->number
- add d0,d5 ; add new digit
- addq #1,d6 ; count digits
- cmp #3,d6 ; 3rd digit added?
- bne.s .getkey ; no-> next key
-
- .makeascii: move d7,d0 ; previous key code
- and #NKFf_CAPS,d0 ; isolate CapsLock flag
- move.b d5,d0 ; add key code (ASCII)
-
-
- *------------- Control key emulation
-
- .ctrlkey: btst.b #NKSb_CTRL,sflags + 3 ; enabled?
- beq.s .deadkey ; no ->
-
- btst.l #NKFb_CTRL,d0 ; Control flag set?
- beq.s .deadkey ; no ->
-
- btst.l #NKFb_ALT,d0 ; Alternate flag set?
- bne.s .deadkey ; yes ->
-
- cmp.b #$40,d0 ; check ASCII code
- blo.s .deadkey ; too low ->
-
- cmp.b #$5f,d0 ; check again
- bhi.s .deadkey ; too high ->
-
- ; clear function and Control flags
- and #(!(NKFf_FUNC|NKFf_CTRL)) & $ffff,d0
- sub.b #$40,d0 ; new ASCII code
-
- * The Pure assembler believes that !(NKFf_FUNC|NKFf_CTRL) is a LONGWORD constant
- * so we have to mask off the upper 16 bits with $ffff. Gosh!
-
-
- *------------- check if key = deadkey
-
- .deadkey: tst d0 ; function key?
- bmi.s .ret ; yes-> no deadkey
-
- lea deadtab,a0 ; ^deadkey table
- move sflags,d4 ; deadkey flags
- beq.s .exit ; no deadkeys at all->
-
- .finddead: move (a0)+,d2 ; get option flag mask
- beq.s .exit ; end of table-> no deadkey
-
- move (a0)+,d1 ; get key code
- addq #4,a0 ; skip ^match table
- and d4,d2 ; is this deadkey enabled?
- beq.s .finddead ; no ->
-
- cmp.b d0,d1 ; deadkey found?
- bne.s .finddead ; no->
-
-
- *------------- key is dead key, get second key and merge them
-
- move.l -4(a0),a5 ; ^deadkey match table
- move d0,-(sp) ; save key code
- clr d0 ; no Alternate check
- jsr (a6) ; get second key
- move sflags,-(sp) ; save deadkey flags
- clr sflags ; disable deadkeys temporary
- move.l a6,a0 ; do ASCII input/ctrl key check
- bsr nk_spec ; by calling myself!
-
- move (sp)+,sflags ; restore deadkey flags
- move (sp)+,d7 ; restore first key code
- tst d0 ; function key?
- bmi.s .nomatch ; yes-> doesn't match with deadkey
-
- .findmatch: move (a5)+,d1 ; merged and second key code
- beq.s .nomatch ; end of table->
-
- cmp.b d0,d1 ; second key code found?
- bne.s .findmatch ; no->
-
- lsr #8,d1 ; yes: merged code in .B
- and #NKFf_CAPS,d0 ; clear all except CapsLock
- move.b d1,d0 ; CapsLock flag + merged key
- bra.s .exit ; exit
-
- .nomatch: move d0,prvkey ; save second key
- st.b prvvalid ; set validation flag
- move d7,d0 ; return first key
-
- .ret: rts ; bye
-
- .exit: tst d0 ; set CCR
- rts ; bye
-
-
-
- ****************************************************************************
- *
- * nk_ascmatch: check if ASCII code matches with one from the key code tables
- * # R
- *
- * This functions proofs, if D0.B equals to D4.B, D5.B or D6.B. An according
- * flag is returned. The flag bytes in the TOS key code D0.L are modified
- * depending on which code matches.
- *
- * In: D0.L key code in TOS format
- * D4.B ASCII code from unshifted key table
- * D5.B ASCII code from shifted key table
- * D6.B ASCII code from CapsLock key table
- *
- * Out: D0.L key code in TOS format
- * (updated flags in upper byte)
- *
- * CCR EQ: ASCII code was found
- * NE: ASCII code wan't found
- *
- * Reg: D:01234567 A:01234567 CCR
- * U......* ........ flag (see above)
- *
- ****************************************************************************
-
- nk_ascmatch: tst.b d0 ; zero?
- bne.s .comp ; no ->
-
- move.l d0,d7 ; copy key code
- ; Alt/Control already found out?
- and.l #(NKFf_ALT|NKFf_CTRL)<<16,d7
- bne.s .unknown ; yes ->
-
- .comp: cmp.b d4,d0 ; unshifted?
- bne.s .shftst ; no ->
-
- cmp.b d6,d0 ; in CapsLock table, too?
- beq.s .exit ; yes ->
-
- bclr.l #NKFb_CAPS+16,d0 ; no: cannot be CapsLock
- bra.s .exit ; ->
-
- .shftst: cmp.b d5,d0 ; shifted?
- bne.s .cpstst ; no ->
-
- cmp.b d6,d0 ; in CapsLock table, too?
- bne.s .shifted ; no ->
-
- btst.l #NKFb_CAPS+16,d0 ; CapsLock active?
- bne.s .exit ; yes -> it COULD be generated
- ; by pressing Shift, but we
- ; assume CapsLock
-
- .shifted: or.l #NKFf_SHIFT<<16,d0 ; shifted: set both shift flags
- bra.s .exit ; ->
-
- .cpstst: cmp.b d6,d0 ; in CapsLock table?
- bne.s .unknown ; no ->
-
- bset.l #NKFb_CAPS+16,d0 ; yes: set CapsLock flag
-
- .exit: moveq.l #0,d7 ; found
- rts
-
- .unknown: moveq.l #1,d7 ; not found
- rts
-
-
-
- ****************************************************************************
- *
- * nk_findscan: find scan code
- * # R
- *
- * The
- *
- * In: D0.W normalized key code
- * A0.L ^base of system's key code table
- *
- * Out: D1.W found scan code (0 = not found)
- * CCR set according contents of D1.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * .W...... *....... =D1
- *
- ****************************************************************************
-
- nk_findscan: btst.l #NKFb_NUM,d0 ; on numeric keypad?
- beq.s .search ; no ->
-
- move #$4a,d1 ; yes: try all numeric keypad
- cmp.b (a0,d1),d0 ; scan codes first
- beq.s .found ; it matches ->
-
- move #$4e,d1
- cmp.b (a0,d1),d0
- beq.s .found
-
- move #$63,d1 ; block starts at $63
-
- .numsearch: cmp.b (a0,d1),d0 ; match?
- beq.s .found ; yes ->
-
- addq #1,d1 ; next scan code
- cmp #$73,d1 ; block end at $72
- blo.s .numsearch ; continue search ->
-
- .search: move #1,d1 ; start with first valid scan code
-
- .mainsearch: cmp.b (a0,d1),d0 ; match?
- beq.s .found ; yes ->
-
- addq.b #1,d1 ; next scan code
- cmp.b #$78,d1 ; $78 = last valid scan code
- blo.s .mainsearch ; continue search ->
-
- moveq.l #0,d1 ; not found
- rts
-
- .found: tst d1 ; found; set CCR
- rts
-
-
-
- .if NKCGEM=1
-
- ****************************************************************************
- *
- * nk_bioscode: convert GEM key code to GEMDOS/BIOS format
- * # R
- *
- * This is a simple converter which takes key codes in AES format (two
- * words) and transforms them to the BIOS key format (one longword).
- *
- * In: D0.W key code
- * high byte = scan code, low byte = ASCII code
- * D1.W shift key state flags
- * Bit 0: right Shift
- * Bit 1: left Shift
- * Bit 2: Control
- * Bit 3: Alternate
- *
- * Out: D0.L key code in BIOS format
- * for details see nkc_tconv()
- *
- * Reg: D:01234567 A:01234567 CCR
- * U*...... *....... *
- *
- ****************************************************************************
-
- nk_bioscode: swap d0 ; key code in high word
- move d1,d0 ; shift key state
- move.l pshift,a0 ; ^shift key state system variable
- move.b (a0),d1 ; get it
- and #!NKFf_CAPS,d1 ; isolate CapsLock flag
- or d1,d0 ; merge with other shift flags
- swap d0 ; shift state in high word
- lsl.l #8,d0 ; move 'em up
- lsr #8,d0 ; now key code in BIOS format
- rts ; bye
-
-
-
- ****************************************************************************
- *
- * nk_real_shift: try to get original shift flags of a key code
- * #
- *
- * This function uses the contents of the Iorec keyboard ring buffer to
- * restore the original shift flag byte of a key code which has been
- * transported through AES' event manager and thus stripped off its
- * flag byte.
- *
- * In: D0.L key code in TOS format
- * for details see nkc_tconv()
- *
- * Out: D0.L updated key code in TOS format
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... *....... *
- *
- ****************************************************************************
-
- nk_real_shift: move.l kbdiorec,a0 ; ^keyboard's I/O record
- movem.l d3/d4,-(sp) ; save registers
- move IBUFHD(a0),d1 ; head pointer
- move IBUFTL(a0),d2 ; tail pointer
- move iohead,d3 ; NKCC's head pointer
-
-
- *------------- check if tail pointer has overrun NKCC's head pointer
-
- cmp d1,d2 ; tail < head?
- blo.s .tlwrap ; yes -> it has been wrapped around
-
- cmp d3,d1 ; my tail between record's
- bhs.s .search ; head and tail?
-
- cmp d2,d3 ; if so, tail has overrun my
- blo.s .reset ; head -> reset
-
- bra.s .search ; no overrun ->
-
- .tlwrap: cmp d2,d3 ; my tail below wrapped record's
- blo.s .reset ; tail pointer or above head?
-
- cmp d3,d1 ; then tail has overrun my
- blo.s .reset ; head -> reset
-
-
- *------------- find key code in ring buffer
-
- .search: move IBUFSIZ(a0),d2 ; buffer size
- move.l IBUF(a0),a0 ; ^base of buffer
- move.l d0,d4 ; copy key code
- swap d4 ; scan code in low byte of d4
- bra.s .find2 ; ->
-
- .find: addq #4,d3 ; advance to next read-position
- cmp d2,d3 ; wrap around?
- blo.s .getkey ; no ->
-
- moveq.l #0,d3 ; yes: wrap
-
- .getkey: cmp.b 3(a0,d3),d0 ; compare ASCII code
- bne.s .find2 ; doesn't match ->
-
- cmp.b 1(a0,d3),d4 ; compare scan code
- bne.s .find2 ; doesn't match ->
-
- move.l (a0,d3),d0 ; found: get complete key code
- bra.s .exit ; ->
-
- .find2: cmp d1,d3 ; my head has reached buffer's head
- bne.s .find ; no ->
-
- .reset: move d1,d3 ; reset head pointer
-
- .exit: move d3,iohead ; save new head pointer
- movem.l (sp)+,d3/d4 ; restore registers
- rts ; bye
-
-
-
- ****************************************************************************
- *
- * nk_mci: multi event console character input
- * # U
- *
- * This function returns when
- *
- * a) either any key is pressed or
- * b) the Alternate key is released
- *
- * The Alternate check can be suppressed by setting the input parameter in
- * D0.W to zero. The routine works then just as a "get key" function.
- *
- * In: D0.W Alternate key check flag:
- * zero = don't check it
- * non-zero = do Alternate check
- *
- * Out: D0.W key code in normalized format
- * for details see nkc_tconv()
- * D1.W flag:
- * zero = D0.W not valid; Alternate was released
- * non-zero = D1.W valid; Alternate still pressed
- * (also returned when Alternate check supressed)
- * CCR set according content of D1.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U***.... ****.... =D1.W
- *
- ****************************************************************************
-
- nk_mci: move d0,d3 ; save Alternate check flag
- move.l pshift,a3 ; ^shift key state variable
-
- .loop: lea nkc_contrl,a0 ; ^control array
- move #25,(a0)+ ; opcode
- move #16,(a0)+ ; size of intin
- move #7,(a0)+ ; size of intout
- move #1,(a0)+ ; size of addrin
- clr (a0) ; size of addrout
-
- lea nkc_intin,a0 ; ^intin array
- move #MU_TIMER|MU_KEYBD,(a0) ; wait for timer and key strokes
- clr.l 7*4(a0) ; waiting time: 0 ms = minimum!
-
- move #200,d0 ; opcode for AES
- move.l #aespb,d1 ; ^AES parameter block
- trap #2 ; call GEM
-
- lea nkc_intout,a0 ; ^intout array
- move (a0),d0 ; event mask
- move.b (a3),d1 ; shift key state
- and #$f,d1 ; clear unused bits
- move #MU_KEYBD,d2 ; did keyboard event occur?
- and d0,d2 ; check bit
- bne.s .keybd ; yes->
-
- move.l kbdiorec,a1 ; ^keyboard's I/O record
- move IBUFHD(a1),iohead ; reset NKCC's head pointer
- tst d3 ; do Alternate check?
- beq.s .loop ; no->
-
- btst.l #3,d1 ; Alternate still pressed?
- bne.s .loop ; yes->
-
- moveq.l #0,d1 ; Alternate released: abort
- rts
-
- .keybd: move 10(a0),d0 ; key code
- bsr nk_bioscode ; convert to BIOS keycode
- bsr nk_real_shift ; try to get original shift flags
- bsr nkc_tconv ; convert to normalized format
- moveq.l #1,d1 ; key code is valid
- rts ; bye
-
-
-
- ****************************************************************************
- *
- * nk_gemtrap: GEM trap handler
- * # S T2
- *
- * This function is linked to the GEM trap vector at initialization time.
- * It waits for evnt_dclick() calls (get/set double click time) and saves
- * new click times in an own buffer.
- *
- * In: D0.W opcode:
- * 115 = VDI
- * 200 = AES
- * A0.L AES/VDI parameter block
- *
- * Out: -
- *
- * Reg: D:01234567 A:01234567 CCR
- * ..*..... **...... *
- *
- ****************************************************************************
-
- XBRA_HD 0 ; XBRA header
-
- nk_gemtrap: cmp #200,d0 ; AES?
- bne.s .exit ; no ->
-
- move.l d1,a0 ; ^parameter block
- move.l (a0),a1 ; ^contrl array
- cmp #26,(a1) ; opcode for evnt_dclick?
- bne.s .exit ; no ->
-
- move.l 8(a0),a1 ; ^intin array
- tst 2(a1) ; set new time?
- beq.s .exit ; no ->
-
- move (a1),d2 ; yes: get new time
- cmp #4,d2 ; limit check
- bls.s .save ; ok: save new value
-
- moveq.l #4,d2 ; out of range: use maximum
-
- .save: move d2,bvar+BI_DCLTIME ; save it
-
- .exit: move.l nk_gemtrap-4(pc),-(sp) ; old vector address
- rts ; jump to old routine
-
-
-
- ****************************************************************************
- *
- * nk_butvec: VDI mouse button change handler
- * # I S
- *
- * This function handles changes of the mouse button state. It is used
- * for NKCC's own button event handler, which consists mainly of this
- * interrupt and the functions nk_bestart() and nk_beend().
- *
- * The handler knows several modes (stored in bvar+BU_BMODE.w):
- *
- * 0 standby mode: no button event in process, waiting for first click
- * 1 wait mode: button event in process, but not yet finished: waiting
- * for a possible second, third ... click
- * 2 hold mode: button event was generated, condition still true (buttons
- * are still pressed): repeat button event
- *
- * In: D0.W current state of mouse buttons
- *
- * Out: D0.W current state of mouse buttons (unchanged)
- *
- * Reg: D:01234567 A:01234567 CCR
- * ........ ........ *
- *
- ****************************************************************************
-
- XBRA_HD nk_bvret ; XBRA header
-
- * Some milliseconds after the installation of this function, the old vector
- * address is not set (VDI has to return first). A mouse click during this
- * time would lead to a system crash because the new handler jumps through
- * this vector. This is the reason why it's initial content points to a
- * RTS instruction. (I know, this is a very very improbable situation, but
- * it IS possible! And that's reason enough to prepare for it and write
- * some silly lines of comment about it!)
-
- nk_butvec: movem.l d5-d7/a0-a1,-(sp) ; save registers
- lea bvar,a1 ; ^button event info block
- move d0,d7 ; new button mask
- move BI_BSTATE(a1),d6 ; requested button state
- eor d6,d7 ; XOR 'em
- move BI_BMASK(a1),d6 ; button mask
- and d6,d7 ; isolate valid bits
- tst BI_REVCOND(a1) ; condition reverse flag
- bne.s .rev ; reverse ->
-
- tst d7 ; 0-> all button conditions true
- seq.b d6 ; if so, the set d6 to $ff
- bra.s .chkmode ; ->
-
- .rev: eor d6,d7 ; invert condition flags
- cmp d6,d7 ; at least one condition true?
- sne.b d6 ; yes -> set d6 to $ff
-
- * the registers contain now:
- *
- * d6.b = button condition flag (0=condition false, $ff=condition true)
- * d7.w = button condition mask (bits with value 0 indicate true condition)
-
- .chkmode: move.b d6,BI_CVALID(a1) ; save flag
- move BI_BMODE(a1),d5 ; check current mode
- beq.s .standby ; standby mode ->
-
- subq #1,d5 ; check if wait mode
- beq.s .wait ; wait mode ->
-
-
- *------------- handler is in HOLD mode
-
- .hold: tst.b d6 ; hold mode: button condition true?
- beq.s .reset ; no ->
-
- move #1,BI_NCLICKS(a1) ; 1 mouse click
- move d0,BI_SBSTATE(a1) ; use current button state
- st.b BI_BEVALID(a1) ; generate mouse click
- bra .exit
-
- .reset: clr BI_BMODE(a1) ; switch to standby mode
- bra.s .exit
-
-
- *------------- handler is in STANDBY mode
-
- .standby: tst.b BI_BEVALID(a1) ; old click still in buffer?
- bne.s .exit ; yes ->
-
- tst.b d6 ; button condition true?
- beq.s .exit ; no ->
-
- move d0,BI_SBSTATE(a1) ; save button state
- moveq.l #1,d5
- move d5,BI_BMODE(a1) ; change to wait mode
- move d5,BI_NCLICKS(a1) ; init # of clicks
-
- lea timetab,a0 ; ^double click time table
- move BI_DCLTIME(a1),d5 ; double click time
- add d5,d5 ; *4 for index
- add d5,d5
- move.l (a0,d5),d5 ; get double click time
- add.l sysclock,d5 ; add current timer value
- move.l d5,BI_BENDTIME(a1) ; save as end time
-
- moveq.l #1,d5 ; find first button
-
- .findbut: add d5,d5 ; next button
- lsr d7 ; check next bit
- bcs.s .findbut ; condition not true ->
-
- lsr d5 ; first found changed button
-
- .dcbut: move d5,BI_DCBUT(a1) ; save double click button mask
- and d0,d5 ; get 'active' state
- move d5,BI_DCSTATE(a1) ; save it
-
- bra.s .exit ; ->
-
-
- *------------- handler is in WAIT mode
-
- .wait: tst.b BI_BEVALID(a1) ; old click still in buffer?
- bne.s .exit ; yes ->
-
- move BI_DCBUT(a1),d5 ; double click button mask
- move BI_PRVBSTATE(a1),d7 ; previous button state
- eor d0,d7 ; get button state changes
- and d5,d7 ; did dclick button state change?
- beq.s .exit ; no ->
-
- and d0,d5 ; isolate state of dclick button
- cmp BI_DCSTATE(a1),d5 ; changed it to 'active' state?
- bne.s .exit ; no ->
-
- moveq.l #1,d7 ; yes: add 1 to # of clicks
- add BI_NCLICKS(a1),d7
- cmp BI_MAXCLICKS(a1),d7 ; > max # of clicks to wait for?
- bhi.s .exit ; yes ->
-
- move d7,BI_NCLICKS(a1) ; no: save new # of clicks
- add.l #TIME_ADD,BI_BENDTIME(a1) ; let user more time to click
-
-
- *------------- leave interrupt
-
- .exit: move d0,BI_PRVBSTATE(a1) ; save button state
- movem.l (sp)+,d5-d7/a0-a1 ; restore registers
- move.l nk_butvec-4(pc),-(sp) ; old vector address
-
- nk_bvret: rts ; jump to old routine
-
-
-
-
- ****************************************************************************
- *
- * nk_bestart: start special handling of button event
- * #
- *
- * In: -
- *
- * Out: D7.W handler mode (used in nk_beend)
- *
- * Reg: D:01234567 A:01234567 CCR
- * **.....W **...... *
- *
- ****************************************************************************
-
- nk_bestart: moveq.l #0,d7 ; default: no special handling
- tst.b buthnd ; our handler installed?
- beq .exit ; no ->
-
- lea nkc_intin,a0 ; ^event mask
- moveq.l #MU_BUTTON,d0 ; request for button event?
- and (a0),d0
- beq .exit ; no ->
-
-
- *------------- configure timer event
-
- lea bvar,a1 ; ^button event variables
- move 2(a0),d7 ; nclicks + reverse flag
- move.b d7,BI_MAXCLICKS+1(a1) ; isolate and save nclicks
- clr.b d7 ; isolate reverse flag
- move d7,BI_REVCOND(a1) ; save reverse flag
- move 4(a0),BI_BMASK(a1) ; save button mask
- move 6(a0),BI_BSTATE(a1) ; save button state
- ; new mouse button parameters:
- clr 4(a0) ; mask = 0
- clr 6(a0) ; state = 0
- moveq.l #1,d7 ; new handler mode
- move d7,2(a0) ; also used for new nclicks
- ; -> button condition always true
-
- *------------- configure timer event
-
- moveq.l #MU_TIMER,d0 ; request for timer event?
- and (a0),d0
- beq.s .no_timer ; no ->
-
- moveq.l #2,d7 ; new mode
- move.l 28(a0),d0 ; time = 0 ms?
- beq.s .exit ; yes: fine, exactly what we need
-
- moveq.l #3,d7 ; new mode
- swap d0 ; time in Motorola format
- cmp.l prvtime,d0 ; identical to previous time?
- beq.s .nulltime ; yes ->
-
- move.l d0,prvtime ; no: save timer event value
- LWDIVU #5,d0,d1 ; convert to 200 Hz resolution
- add.l sysclock,d0 ; + current timer value
- move.l d0,tendtime ; this is our timer end value
-
- bra.s .nulltime ; and set own one
-
-
- *------------- user doesn't want timer events - but we need them!
-
- .no_timer: moveq.l #-1,d0 ; reset previous timer event value
- move.l d0,prvtime
- or #MU_TIMER,(a0) ; set bit: check timer events
-
- .nulltime: clr.l 28(a0) ; time: 0 ms
-
- .exit: rts ; bye
-
-
-
-
- ****************************************************************************
- *
- * nk_beend: end special handling of button event
- * #
- *
- * In: D7.W handler mode:
- * 0 button event handler inactive
- * 1 user did not check timer events
- * 2 user did check timer events with time = 0 ms
- * 3 user did check timer events with time > 0 ms
- *
- * Out: nkc_intout.W[]:updated mouse event information
- *
- * Reg: D:01234567 A:01234567 CCR
- * **...... **...... *
- *
- ****************************************************************************
-
- nk_beend: lea nkc_intout,a0 ; ^event mask
- move d7,d0 ; which mode?
- beq .exit ; no special handling
-
- lea bvar,a1 ; ^button event info block
- move BI_PRVBSTATE(a1),6(a0) ; return button state
-
-
- *------------- analyze which events have occured
-
- moveq.l #MU_MESAG,d1 ; did message event occur?
- and (a0),d1 ; and with event mask
- beq.s .chkflag ; no message event ->
-
- and #!MU_BUTTON,(a0) ; no button event
-
- .chkflag: moveq.l #MU_BUTTON,d1 ; did button event occur?
- and (a0),d1 ; (if not: just moving a window
- ; or something like that)
- beq.s .lock ; no -> lock mouse button event
-
-
- *------------- application has mouse under its control; what now?
-
- tst.b BI_LOCK(a1) ; is button event locked?
- bne .unlock ; yes -> unlock it
-
- tst.b BI_BEVALID(a1) ; event valid?
- bne.s .butev ; yes ->
-
-
- *------------- mouse click isn't finished, yet; wait
-
- move BI_BMODE(a1),d1 ; no: get handler mode
- beq.s .nombut ; standby mode ->
-
- subq #1,d1 ; wait mode?
- beq.s .wait ; yes ->
-
- .hold: clr 12(a0) ; # of clicks = 0
- bra.s .evtimer
-
- .wait: move.l BI_BENDTIME(a1),d1 ; button event end time
- cmp.l sysclock,d1 ; end of time reached?
- bhi.s .nombut ; no ->
-
- addq #1,BI_BMODE(a1) ; change to hold mode
- tst.b BI_CVALID(a1) ; was last button condition valid?
- bne.s .butev ; yes ->
-
- clr BI_BMODE(a1) ; no: standby mode
-
- .butev: move BI_NCLICKS(a1),12(a0) ; return # of clicks
- move BI_SBSTATE(a1),6(a0) ; return start button state
- sf.b BI_BEVALID(a1) ; button event fetched
- bra.s .evtimer
-
- .nombut: and #!MU_BUTTON,(a0) ; no mouse button event
-
-
- *------------- timer event handling
-
- .evtimer: subq #1,d0 ; timer event checked by us?
- beq.s .nktimer ; yes ->
-
- subq #1,d0 ; 0 ms timer checked by user?
- beq.s .exit ; yes ->
-
- .user0: move.l tendtime,d1 ; timer event end time
- cmp.l sysclock,d1 ; end of waiting time reached?
- bls.s .exit ; yes ->
-
- .nktimer: and #!MU_TIMER,(a0) ; no timer event occured
-
- .exit: move (a0),d0 ; event mask
- and #MU_TIMER,d0 ; did a timer event occur?
- beq.s .exit2 ; no ->
-
- .treset: moveq.l #-1,d0 ; yes: reset previous timer
- move.l d0,prvtime ; event value
-
- .exit2: rts
-
-
- *------------- AES didn't return MU_BUTTON -> screen manager has taken mouse
- * control: don't create MU_BUTTON events
-
- .lock: st.b BI_LOCK(a1) ; lock mouse button event
- move #MU_XTIMER,d1 ; lock timer events, too?
- and nkc_intin,d1 ; check this flag
- beq.s .evtimer ; don't lock ->
-
- bra.s .nktimer ; lock ->
-
-
- *------------- AES did return MU_BUTTON (applications has mouse under its
- * control) but the button events were locked previously: unlock
- * them
-
- .unlock: sf.b BI_LOCK(a1) ; unlock mouse button event
- clr BI_BMODE(a1) ; reset mode
- sf.b BI_BEVALID(a1) ; reset button event flag
- bra.s .nombut
-
-
-
- ****************************************************************************
- *
- * nk_mctrl: set control array for multi event
- * #
- *
- * In: -
- *
- * Out: nkc_contrl.W[]: control parameters configured for evnt_multi() call
- *
- * Reg: D:01234567 A:01234567 CCR
- * ........ *....... *
- *
- ****************************************************************************
-
- nk_mctrl: lea nkc_contrl,a0 ; ^control array
- move #25,(a0)+ ; opcode
- move #16,(a0)+ ; size of intin
- move #7,(a0)+ ; size of intout
- move #1,(a0)+ ; size of addrin
- clr (a0) ; size of addrout
- rts ; bye
-
-
-
-
- ****************************************************************************
- *
- * nk_msave: save input parameters for evnt_multi() call in buffer
- * #
- *
- * In: -
- *
- * Out: multibuf.W[]: first 16 words of nkc_intin and first long of
- * nkc_adrin
- *
- * Reg: D:01234567 A:01234567 CCR
- * *******. **...... *
- *
- ****************************************************************************
-
- nk_msave: lea nkc_intin,a0 ; ^intin array
- lea multibuf,a1 ; ^save buffer
- movem.l (a0)+,d0-d6 ; get first 14 words of nkc_intin
- movem.l d0-d6,(a1) ; save 'em in buffer
- move.l (a0),7*4(a1) ; save last two words
- move.l nkc_adrin,8*4(a1) ; save contents of addrin
- rts
-
-
-
-
- ****************************************************************************
- *
- * nk_mrestore: restore evnt_multi() input parameters corrupted by AES(!)
- * #
- *
- * In: -
- *
- * Out: nkc_contrl.w[]: restored data (5 words)
- * nkc_intin.w[] : restored data (16 words)
- * nkc_adrin.L[] : restored data (1 longword)
- *
- * Reg: D:01234567 A:01234567 CCR
- * *******. **...... *
- *
- ****************************************************************************
-
- nk_mrestore: lea multibuf,a0 ; ^save buffer
- lea nkc_intin,a1 ; ^intin array
- movem.l (a0)+,d0-d6 ; first 14 words of nkc_intin
- movem.l d0-d6,(a1) ; put them in nkc_intin array
- move.l (a0)+,7*4(a1) ; last two words
- move.l (a0),nkc_adrin ; restore addrin array
- bra.s nk_mctrl ; restore contrl array
-
- .endif ; .if NKCGEM=1
-
-
-
-
- ****************************************************************************
- *
- * nk_200hz: 200 Hz system clock interrupt
- * # I S
- *
- * In: -
- *
- * Out: -
- *
- * Reg: D:01234567 A:01234567 CCR
- * ........ ........ *
- *
- ****************************************************************************
-
- XBRA_HD 0 ; XBRA header
-
- nk_200hz: move.l _hz_200,sysclock ; just transfer value
- move.l nk_200hz-4(pc),-(sp) ; old vector address
- rts ; jump to old routine
-
-
-
- *START
- ****************************************************************************
- * GLOBAL TEXT SECTION *
- ****************************************************************************
- *END
-
- .text
-
- *START
- ****************************************************************************
- *
- * nkc_init: initialize NKCC
- * # G U
- *
- * C prototype: int nkc_init(unsigned long flags,int vdihnd,int *pglobal);
- *---------------------------------------------------------------------------
- * This function initializes NKCC. It must be called once before any other
- * NKCC routine. It performs some tasks that may be important for you to
- * know:
- *
- * - bit 3 of the system variable <conterm> ($484.B) is set
- * - a 200 Hz clock interrupt is installed, using the XBRA method (ID is
- * "NKCC")
- *
- * nkc_init() gets some flags which configure NKCC and enable some special
- * functions:
- *
- * NKI?_BUTHND install NKCC's button event handler (see documentation
- * NKCC.DOC for details)
- * NKI?_BHTOS additional flag: install only, if TOS has mouse click bug
- * NKI?_NO200HZ don't install the 200 Hz timer interrupt
- *
- * Notes:
- *
- * - if NKCC is assembled as TOS-only version (symbol NKCGEM set to 0),
- * both NKI?_BUTHND and NKI?_BHTOS flags are ignored.
- *
- * - if the button event handler is installed, the NKI?_NO200HZ flag is
- * ignored (because the 200 Hz clock is needed by the handler). Besides,
- * the initialization continues:
- *
- * - an own GEM trap handler (trap #2) is installed, using the XBRA method
- * (to be up to date when a new double click time is set via the AES
- * function evnt_dclick())
- *
- * - a vex_butv() call (VDI) is made to install a mouse button exchange
- * handler
- *
- * In: D0.L miscellaneous flags (NKI?_...); see above
- * D1.W handle of an open VDI workstation
- * (must only be valid if the button handler is
- * installed)
- * A0.L ^applications GLOBAL array (from GEM parameter block)
- * not used in the TOS version of NKCC
- *
- * Out: D0.W NKCC's version number as 4 digit BCD
- * (main # in high byte, sub # in low byte)
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_init: move.l a2,-(sp) ; save a2 for Turbo C/Pure C
-
- movem.l d0-d1,-(sp) ; save flags and VDI handle
- subq.l #2,sp ; one word local stack space
-
- .if NKCGEM=1
-
- move.l a0,aespb+4 ; keep ^global array
-
- move #1,-(sp) ; device: keyboard
- move #14,-(sp) ; function opcode: Iorec
- trap #14 ; XBIOS
- addq.l #4,sp ; clean stack
- move.l d0,kbdiorec ; keep ^IOREC structure
- move.l d0,a0 ; load into address register
- move IBUFHD(a0),iohead ; keep current head pointer
-
- .endif ; .if NKCGEM=1
-
-
- *------------- switch to Supervisor mode to have access to system variables
-
- clr.l -(sp) ; use usp as ssp
- move #$20,-(sp) ; Super
- trap #1 ; GEMDOS
- move.l d0,2(sp) ; save old sp
- move #$20,(sp) ; Super opcode for next call
-
-
- *------------- enable auto return of shift/ctrl/alt status
-
- bset.b #3,conterm.w ; set bit for auto shift return
-
-
- *------------- locate shift state system variable
-
- move.l _sysbase.w,a0 ; ^OS header
- move 2(a0),d0 ; get TOS version
- move d0,6(sp) ; save it in local stack space
- cmp #$0100,d0 ; TOS 1.0?
- beq.s .tos10 ; yes ->
-
- move.l $24(a0),pshift ; get ^shift state variable
- bra.s .user ; ->
-
- .tos10: move.l #$e1b,pshift ; this is the location in TOS 1.0
-
-
- *------------- switch back to user mode
-
- .user: trap #1 ; GEMDOS
- addq #6,sp ; clean stack
-
-
- *------------- fetch addresses of TOS' key scan code translation tables
-
- moveq.l #-1,d0 ; the function is also used to
- move.l d0,-(sp) ; change the addresses; values
- move.l d0,-(sp) ; of -1 as new addresses tell
- move.l d0,-(sp) ; XBIOS not to change them
- move #$10,-(sp) ; Keytbl
- trap #14 ; XBIOS
- lea $e(sp),sp ; clean stack
-
- move.l d0,a0 ; ^key table structure
- move.l (a0)+,pkey_unshift ; get ^unshifted table
- move.l (a0)+,pkey_shift ; get ^shifted table
- move.l (a0),pkey_caps ; get ^CapsLock table
-
-
- *------------- do some other initialization stuff
-
- clr.l sflags ; reset special key flags
- clr.b prvvalid ; no previous key code
-
-
- *------------- install the mouse button handler
-
- move (sp)+,d0 ; TOS version
- movem.l (sp),d1-d2 ; restore flags and VDI handle
-
- .if NKCGEM=1
-
- clr.b buthnd ; default: set flag: not installed
- btst.l #NKIb_BUTHND,d1 ; install it?
- beq .timer ; no ->
-
- btst.l #NKIb_BHTOS,d1 ; check TOS version number?
- beq.s .butev ; no ->
-
- cmp #$0104,d0 ; bug appeared in TOS 1.04!
- blo .timer ; TOS is ok ->
-
- cmp #$0306,d0 ; bug is solved since TOS 3.06!
- bhs .timer ; TOS is ok ->
-
- .butev: bclr.l #NKIb_NO200HZ,d1 ; must install timer interrupt
- st.b buthnd ; set flag: handler installed
- move d2,vdihnd ; save VDI handle
-
- moveq.l #0,d0 ; do some initializations
- lea bvar,a1 ; ^button event info block
- move d0,BI_BMODE(a1) ; init interrupt mode
- move.b d0,BI_BEVALID(a1) ; mouse click info not valid
- move d0,BI_PRVBSTATE(a1) ; init previous button state
- move d0,BI_BMASK(a1) ; don't check any button
- move.b d0,BI_LOCK(a1) ; mouse button event isn't locked
- subq.l #1,d0 ; d0.l = -1
- move d0,BI_REVCOND(a1) ; reverse button condition
- ; -> no mouse click is checked
- move.l d0,prvtime ; previous timer event value
-
- lea nkc_contrl,a0 ; set parameter array for vex_butv
- move #125,(a0)+ ; opcode
- clr.l (a0)+ ; no ptsin/ptsout entries
- clr.l (a0)+ ; no intin/intout entries
- addq #2,a0 ; entry #5 is unused
- move d2,(a0)+ ; handle of workstation
- lea nk_butvec(pc),a1 ; ^our handler
- move.l a1,(a0)
- moveq.l #115,d0 ; opcode: VDI
- move.l #vdipb,d1 ; ^parameter block
- trap #2 ; execute VDI
- move.l nkc_contrl+18,nk_butvec-4 ; save old handler address
-
- lea nkc_contrl,a0 ; set parameter for evnt_dclick
- move #26,(a0)+ ; opcode
- move #2,(a0)+ ; # of entries in intin
- move #1,(a0)+ ; # of entries in intout
- clr.l (a0)+ ; no entries in addrin/addrout
- clr nkc_intin+2 ; get/set flag: get value
- move #200,d0 ; opcode for AES
- move.l #aespb,d1 ; ^parameter block
- trap #2 ; execute AES
- move nkc_intout,bvar+BI_DCLTIME ; save double click time
-
- ; install trap #2 handler
- moveq.l #34,d0 ; vector number
- moveq.l #NKXM_NUM,d1 ; mode: vector number
- lea nk_gemtrap(pc),a0 ; ^function to install
- bsr nkc_vlink ; install it
-
- .endif ; .if NKCGEM=1
-
-
- *------------- install 200 Hz clock interrupt
-
- .timer: clr.l sysclock ; init 200 Hz clock for the case
- ; that the timer won't be installed
- movem.l (sp)+,d1-d2 ; restore flags and VDI handle
- btst.l #NKIb_NO200HZ,d1 ; install interrupt?
- seq.b timerflag ; $00 = no, $ff = yes
- bne.s .exit ; no ->
-
- moveq.l #69,d0 ; vector number
- moveq.l #NKXM_NUM,d1 ; mode: vector number
- lea nk_200hz(pc),a0 ; ^function to install
- bsr nkc_vlink ; install it
-
-
- *------------- restore saved register and exit
-
- .exit: move.l (sp)+,a2 ; restore register
- move #VERSION,d0 ; load version #
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_exit: exit NKCC
- * # G U
- *
- * C prototype: int nkc_exit(void);
- *---------------------------------------------------------------------------
- * nkc_exit() must be called before the program is quit. It removes all
- * handlers installed in the system.
- *
- * In: -
- *
- * Out: D0.W status flag:
- * 0 OK
- * -1 can't remove 200 Hz clock interrupt
- * -2 can't remove trap #2 handler
- * -3 can't remove both handlers
- * An error can happen if somebody corrupted the
- * XBRA vector list. This is fatal!
- *
- * Reg: D:01234567 A:01234567 CCR
- * ***..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_exit: move.l a2,-(sp) ; save register
-
-
- *------------- remove 200 Hz system clock interrupt
-
- clr -(sp) ; default remove status for
- ; timer interrupt
- tst.b timerflag ; installed?
- beq.s .buthnd ; no ->
-
- moveq.l #69,d0 ; vector number
- moveq.l #NKXM_NUM,d1 ; mode: vector number
- lea nk_200hz(pc),a0 ; ^function to remove
- bsr nkc_vunlink ; remove it
- move d0,(sp) ; save remove status
-
-
- *------------- remove own button event handler
-
- .buthnd: clr -(sp) ; default remove status for
- ; button event handler
-
- .if NKCGEM=1
-
- tst.b buthnd ; handler installed?
- beq.s .exit ; no ->
-
- lea nkc_contrl,a0 ; set paremeter array for vex_butv
- move #125,(a0)+ ; opcode
- clr.l (a0)+ ; no ptsin/ptsout entries
- clr.l (a0)+ ; no intin/intout entries
- addq #2,a0 ; entry #5 is unused
- move vdihnd,(a0)+ ; handle of workstation
- lea nk_butvec(pc),a1 ; ^our handler
- move.l -4(a1),(a0) ; ^old routine
- moveq.l #115,d0 ; opcode: VDI
- move.l #vdipb,d1 ; ^parameter block
- trap #2 ; execute VDI
-
- ; remove trap #2 handler
- moveq.l #34,d0 ; vector number
- moveq.l #NKXM_NUM,d1 ; mode: vector number
- lea nk_gemtrap(pc),a0 ; ^function to remove
- bsr nkc_vunlink ; remove it
- move d0,(sp) ; save status
-
- .endif ; .if NKCGEM=1
-
-
- *------------- restore saved registers and exit
-
- .exit: move (sp)+,d0 ; trap #2 remove error?
- beq.s .stat0 ; no ->
-
- move (sp)+,d0 ; 200 Hz clock remove error?
- beq.s .stat1 ; no ->
-
- moveq.l #-3,d0 ; both failed!
- bra.s .ret
-
- .stat0: move (sp)+,d0 ; 200 Hz clock remove error?
- beq.s .ret ; no ->
-
- moveq.l #-1,d0 ; "only" 200 Hz clock failure?
- bra.s .ret
-
- .stat1: moveq.l #-2,d0 ; "only" trap #2 remove failure?
-
- .ret: move.l (sp)+,a2 ; restore register
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_set: set special key flags
- * # G
- *
- * C prototype: void nkc_set(unsigned long flags);
- *---------------------------------------------------------------------------
- * This function is used to enable/disable special key handling procedures.
- * The features which can be set are:
- *
- * - direct input of ASCII codes; when switched on, pressing the Alternate
- * key plus one of the numbers on the numeric keypad will start the input
- * of a decimal ASCII number. The input is finished either when 3 digits
- * are typed in or the Alternate key is released. NKCC will return the
- * corresponding character with the entered ASCII code. This feature makes
- * it possible to use the whole range of the character set (from 0 ... 255).
- *
- * - deadkey management; when switched on, NKCC will combine some combi-
- * nations of two key strokes to one character. This is used to generate
- * characters with accents which are not on the keyboard. The supported
- * deadkeys are:
- *
- * ^ + aeiou = âêîôû (NKS?_D_CIRCUM)
- * ~ + nNaoAo = ñÑãõÃÕ (NKS?_D_TILDE)
- * ' + eEaiou = éÉáíóú (NKS?_D_AGUI)
- * ` + aeiouA = àèìòùÀ (NKS?_D_GRAVE)
- * ¨ + aeiouyAOU = äëïöüÿÄÖÜ (NKS?_D_UMLAUT)
- * " + aeiouyAOU = äëïöüÿÄÖÜ (NKS?_D_QUOTE)
- * ° + aA = åÅ (NKS?_D_SMOERE)
- * , + cC = çÇ (NKS?_D_CEDIL)
- * / + oO24 = øؽ¼ (NKS?_D_SLASH)
- *
- * The quote character as synonym for umlaut is e.g. needed on the Dutch
- * keyboard, where neither umlaut characters nor the umlaut itself are
- * available.
- *
- * Each deadkey can be enabled/disabled separately.
- *
- * - Control key emulation: Control plus an ASCII code in the range of
- * $40...$5F (characters @, A...Z, [, \, ], ^ and _) is converted
- * to an ASCII code of $00...$1F.
- *
- *
- * In: D0.L new key flags (bit set = feature on):
- * NKS?_ALTNUM ASCII input
- * NKS?_D_... deadkey ...
- * (NKSf_DEADKEY: all deadkeys)
- * NKS?_CTRL control key emulation
- *
- * Out: -
- *
- * Reg: D:01234567 A:01234567 CCR
- * ***..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_set: move.l d0,sflags ; just save flags
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_conin: raw console character input
- * # G
- *
- * C prototype: int nkc_conin(void);
- *---------------------------------------------------------------------------
- * This routine replaces the Gemdos function Crawcin. However, it returns
- * a WORD with the key code in normalized format rather than a LONG with
- * the key code in the language dependend TOS format.
- *
- * In: -
- *
- * Out: D0.W key code in normalized format
- * for details see nkc_tconv()
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * W**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_conin: tst.b prvvalid ; previous character in buffer?
- beq.s .getkey ; no->
-
- clr.b prvvalid ; remove key code from buffer
- move prvkey,d0 ; get key code
- rts ; bye
-
-
- .getkey: movem.l d3-d7/a2-a6,-(sp) ; save registers
- clr d0 ; don't check Alternate state
- bsr nk_gci ; get key code
- lea nk_gci(pc),a0 ; ^function to execute
- bsr nk_spec ; special key handling
- movem.l (sp)+,d3-d7/a2-a6 ; restore registers
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_cstat: return console character input status
- * # G
- *
- * C prototype: int nkc_cstat(void);
- *---------------------------------------------------------------------------
- * This function checks, if a key is in the key input buffer or not.
- *
- * In: -
- *
- * Out: D0.W flag:
- * 0 no key in buffer
- * -1 at least one key in buffer
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * W**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_cstat: tst.b prvvalid ; previous character in buffer?
- sne.b d0 ; $ff = yes, $00 = no
- ext d0 ; as word
- bne.s .exit ; char available: exit
-
- move.l a2,-(sp) ; save register for Turbo C/Pure C
-
- move #11,-(sp) ; Cconis
- trap #1 ; Gemdos
- addq #2,sp ; clean stack
-
- move.l (sp)+,a2 ; restore register
- tst d0 ; set CCR
-
- .exit: rts ; bye
-
-
-
- .if NKCGEM=1
-
- *START
- ****************************************************************************
- *
- * nkc_multi: NKCC multi event
- * # G U
- *
- * C prototype: int cdecl nkc_multi(
- * int mflags,
- * int mbclicks,int mbmask,int mbstate,
- * int mm1flags,int mm1x,int mm1y,int mm1width,int mm1height,
- * int mm2flags,int mm2x,int mm2y,int mm2width,int mm2height,
- * int *mmgpbuff,
- * int mtlocount,int mthicount,
- * int *mmox,int *mmoy,int *mmbutton,int *mmokstate,
- * int *mkreturn,int *mbreturn);
- *---------------------------------------------------------------------------
- * nkc_multi() is a binding function to the AES multi event handler. The
- * only differences are the keyboard events and the shift key state: the key
- * codes are returned in normalized format (see nkc_tconv()), the shift key
- * state is compatible to the NKF?_... flags. For a detailed description of
- * the whole mass of parameters consult your AES manual or compiler handbook!
- *
- * In: 4(SP).w event mask (MU_...)
- * 6(SP).w MU_BUTTON: max # of clicks to wait for
- * 8(SP).w MU_BUTTON: mask of buttons to check
- * 10(SP).w MU_BUTTON: button states to wait for
- * 12(SP).w MU_M1: area enter/leave flag
- * 14(SP).w MU_M1: x position of area
- * 16(SP).w MU_M1: y position of area
- * 18(SP).w MU_M1: width of area
- * 20(SP).w MU_M1: height of area
- * 22(SP).w MU_M2: area enter/leave flag
- * 24(SP).w MU_M2: x position of area
- * 26(SP).w MU_M2: y position of area
- * 28(SP).w MU_M2: width of area
- * 30(SP).w MU_M2: height of area
- * 32(SP).L MU_MESAG: ^8 words of message buffer
- * 36(SP).w MU_TIMER: low word of time to wait
- * 38(SP).w MU_TIMER: high word of time to wait
- * 40(SP).L MU_BUTTON/M1/M2: ^word for mouse x
- * 44(SP).L MU_BUTTON/M1/M2: ^word for mouse y
- * 48(SP).L MU_BUTTON/M1/M2: ^word for button state
- * 52(SP).L MU_BUTTON/M1/M2: ^word for shift state
- * 56(SP).L MU_KEYBD: ^word for key code in normalized format
- * 60(SP).L MU_BUTTON: ^word for # of mouse clicks
- *
- * Out: D0.W mask of occured events (MU_...)
- *
- * Reg: D:01234567 A:01234567 CCR
- * W**..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_multi: tst.b prvvalid ; previous character in buffer?
- beq.s .mevent ; no ->
-
- clr.b prvvalid ; remove key code from buffer
- move.l 56(sp),a0 ; ^buffer for key code
- move prvkey,(a0) ; return key code
- moveq.l #MU_KEYBD,d0 ; a keyboard event occured
- rts ; bye
-
- .mevent: movem.l d3-d7/a2-a6,-(sp) ; save registers
-
-
- *------------- transfer stack arguments to GEM parameter arrays
-
- lea 10*4+4(sp),a0 ; ^first parameter
- lea nkc_intin,a1 ; ^integer in array
- movem.l (a0)+,d1-d7 ; get the first 14 words
- movem.l d1-d7,(a1) ; place them in intin
- move.l (a0)+,nkc_adrin ; ^message buffer in addrin
- move.l (a0),7*4(a1) ; timer event lo and hi count
-
- bsr nk_mctrl ; setup control array
-
-
- *------------- execute multi event
-
- bsr nk_bestart ; start handling for button event
- bsr nk_msave ; save multi event parameters
-
- .wait: cmp #25,nkc_contrl ; still evnt_multi() opcode?!?
- beq.s .aes ; yes ->
-
- bsr nk_mrestore ; NO! AES corrupted it! restore
-
- .aes: lea nkc_intin,a0 ; ^intin
- move (a0),-(sp) ; save event mask
- and #!MU_XTIMER,(a0) ; clear x-timer flag
- move #200,d0 ; opcode for AES
- move.l #aespb,d1 ; ^AES parameter block
- trap #2 ; call GEM
- move (sp)+,nkc_intin ; restore event mask
-
- move nkc_intout,d0 ; mask of occured events
- and #MU_KEYBD,d0 ; keyboard event?
- bne.s .buthnd ; yes ->
-
- move.l kbdiorec,a0 ; no: get ^keyboard's I/O record
- move IBUFHD(a0),iohead ; reset NKCC's head pointer
-
- .buthnd: bsr nk_beend ; end handling of button event
- tst nkc_intout ; did any event occur?
- beq.s .wait ; no ->
-
-
- *------------- return intout parameters via pointers
-
- movem.l 10*4+40(sp),a0-a5 ; get return pointers
- lea nkc_intout,a6 ; ^intout array
- move (a6)+,d0 ; mask of occured events
- move (a6)+,(a0) ; mouse x
- move (a6)+,(a1) ; mouse y
- move (a6)+,(a2) ; mouse button state
- move.b 1(a6),(a3) ; shift key state (NKC flag
- ; compatible!)
- clr.b 1(a3) ; clear low byte of shift state
- move.l a6,a3 ; ^shift state in intout
- move 4(a6),(a5) ; # of mouse clicks
- move 2(a6),(a4) ; key code
-
- * You wonder why (a4) is written as last one and (a3) points to intout
- * instead of the original return location? This is for the case that
- * the caller isn't interested in one or some of the return values and
- * let them point to ONE dummy variable.
-
-
- *------------- check if keyboard event occured and convert key code, if so
-
- moveq.l #MU_KEYBD,d1 ; the flag to test
- and d0,d1 ; is it set?
- beq.s .exit ; no-> exit
-
- move d0,-(sp) ; save event mask
- move.l a4,-(sp) ; save ^key code
-
- move (a4),d0 ; scan code + ASCII code
- moveq.l #MU_BUTTON|MU_M1|MU_M2,d1 ; any of the events checked
- and 10*4+4+6(a7),d1 ; which return shift state?
- bne.s .useiout ; yes->
-
- move.l pshift,a3 ; no: get shift state directly
- move.b (a3),d1 ; get it
- and #$f,d1 ; isolate valid bits
- bra.s .conv
-
- .useiout: move (a3),d1 ; get shift state from intout
-
- .conv: bsr nk_bioscode ; convert to BIOS format
- bsr nk_real_shift ; try to get original shift flags
- bsr nkc_tconv ; convert to normalized format
- lea nk_mci(pc),a0 ; ^function to execute
- bsr nk_spec ; special key code handling
-
- move.l (sp)+,a0 ; restore ^key code
- move d0,(a0) ; return key code
-
- move (sp)+,d0 ; restore event mask
- move d0,nkc_intout ; and intout (changed by nk_spec)
-
- .exit: movem.l (sp)+,d3-d7/a2-a6 ; restore registers
- rts ; bye
-
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_amulti: NKCC multi event called by Assembler *** added by Gerd Knops
- * # G U
- *
- * See description of nkc_multi()!
- *
- * usage: instead of move.l #aespb,d1
- * move #$c8,d0
- * trap #2
- *
- * do jsr nkc_amulti
- *
- * In: all parameters for evnt_multi in the AES parameter arrays
- *
- * Out: values in intout and message buffer
- *
- * Reg: D:01234567 A:01234567 CCR
- * ***..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_amulti: tst.b prvvalid ; previous character in buffer?
- beq.s .mevent ; no->
-
- clr.b prvvalid ; remove key code from buffer
- clr nkc_intout+8 ; no SHIFT etc.
- move prvkey,nkc_intout+10 ; return key code
- move #MU_KEYBD,nkc_intout ; a keyboard event occured
- rts ; bye
-
- .mevent: movem.l d3-d7/a2-a6,-(sp) ; save registers
-
- move nkc_intin,-(sp) ; events to get
-
-
- *------------- execute multi event
-
- bsr nk_bestart ; start handling for button event
- bsr nk_msave ; save multi event parameters
-
- .wait: cmp #25,nkc_contrl ; still evnt_multi() opcode?!?
- beq.s .aes ; yes ->
-
- bsr nk_mrestore ; NO! AES corrupted it! restore
-
- .aes: lea nkc_intin,a0 ; ^intin
- move (a0),-(sp) ; save event mask
- and #!MU_XTIMER,(a0) ; clear x-timer flag
- move #200,d0 ; opcode for AES
- move.l #aespb,d1 ; ^AES parameter block
- trap #2 ; call GEM
- move (sp)+,nkc_intin ; restore event mask
-
- move nkc_intout,d0 ; mask of occured events
- and #MU_KEYBD,d0 ; keyboard event?
- bne.s .buthnd ; yes ->
-
- move.l kbdiorec,a0 ; no: get ^keyboard's I/O record
- move IBUFHD(a0),iohead ; reset NKCC's head pointer
-
- .buthnd: bsr nk_beend ; end handling of button event
- tst nkc_intout ; did any event occur?
- beq.s .wait ; no ->
-
- move (sp)+,d2 ; events to get
-
-
- *------------- check if keyboard event occured and convert key code, if so
-
- lea nkc_intout+8,a3 ; ^shift key state
- move (a3),d0 ; make in NKF?_... compatible
- move.b d0,(a3)
- clr.b 1(a3)
-
- move nkc_intout,d0 ; mask of received events
- moveq.l #MU_KEYBD,d1 ; the flag to test
- and d0,d1 ; is it set?
- beq.s .exit ; no-> exit
-
- move d0,-(sp) ; save event mask
-
- move nkc_intout+10,d0 ; scan code + ASCII code
- moveq.l #MU_BUTTON|MU_M1|MU_M2,d1 ; any of the events checked
- and d2,d1 ; which return shift state?
- bne.s .useiout ; yes->
-
- move.l pshift,a3 ; no: get shift state directly
- move.b (a3),d1 ; get it
- and #$f,d1 ; isolate valid bits
- bra.s .conv
-
- .useiout: move nkc_intout+8,d1 ; get shift state from intout
- lsr #8,d1 ; in TOS format
-
- .conv: bsr nk_bioscode ; convert to BIOS format
- bsr nk_real_shift ; try to get original shift flags
- bsr.s nkc_tconv ; convert to normalized format
- lea nk_mci(pc),a0 ; ^function to execute
- bsr nk_spec ; special key code handling
-
- move d0,nkc_intout+10 ; save keycode
- move (sp)+,d0 ; restore event mask
- move d0,nkc_intout ; and intout (changed by nk_spec)
-
- .exit: movem.l (sp)+,d3-d7/a2-a6 ; restore registers
- rts ; bye
-
- .endif ; .if NKCGEM=1
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_tconv: TOS key code converter
- * # G R
- *
- * C prototype: int nkc_tconv(long toskey);
- *---------------------------------------------------------------------------
- * This is the most important function within NKCC: it takes a key code
- * returned by TOS and converts it to the sophisticated normalized format.
- *
- * Note: the raw converter does no deadkey handling, ASCII input or
- * Control key emulation.
- *
- * In: D0.L key code in TOS format:
- * 0 1
- * bit 31: ignored ignored
- * bit 30: ignored ignored
- * bit 29: ignored ignored
- * bit 28: no CapsLock CapsLock
- * bit 27: no Alternate Alternate pressed
- * bit 26: no Control Control pressed
- * bit 25: no left Shift key left Shift pressed
- * bit 24: no right Shift key right Shift pressed
- *
- * bits 23...16: scan code
- * bits 15...08: ignored
- * bits 07...00: ASCII code (or rubbish in most cases
- * when Control or Alternate is pressed ...)
- *
- * Out: D0.W normalized key code:
- * bits 15...08: flags:
- * 0 1
- * NKF?_FUNC printable char "function key"
- * NKF?_RESVD ignore it ignore it
- * NKF?_NUM main keypad numeric keypad
- * NKF?_CAPS no CapsLock CapsLock
- * NKF?_ALT no Alternate Alternate pressed
- * NKF?_CTRL no Control Control pressed
- * NKF?_LSH no left Shift key left Shift pressed
- * NKF?_RSH no right Shift key right Shift pressed
- *
- * bits 07...00: key code
- * function (NKF?_FUNC set):
- * < 32: special key (NK_...)
- * >=32: printable char + Control and/or Alternate
- * no function (NKF?_FUNC not set):
- * printable character (0...255!!!)
- *
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... =D0.W
- *
- ****************************************************************************
- *END
- *
- * Usage of the NKF?_RESVD flag:
- *
- * If the flag is set, the function nkc_cmp(), which evaluates the flag,
- * has to check the state of the shift keys when comparing two key codes.
- *
- * Don't use the flag outside NKCC! Its content and meaning may change
- * in future versions without notice!
- *
- ****************************************************************************
-
- nkc_tconv: movem.l d3/d4,-(sp) ; save registers
-
-
- *------------- separate TOS key code
-
- move.l d0,d1 ; TOS key code
- swap d1 ; .W = scan code and flags
- move d1,d2 ; copy
- move #$ff,d3 ; and-mask
- and d3,d0 ; .B = ASCII code
- and d3,d1 ; .B = scan code
- beq .tos306 ; scancode=zero (key code created
- ; by ASCII input of TOS 3.06)? ->
- and #$1f00,d2 ; .W = key flags (in high byte)
-
-
- *------------- decide which translation table to use
-
- move d2,d3 ; key flags
- and #NKFf_SHIFT,d3 ; isolate bits for shift keys
- beq.s .ktab1 ; shift key pressed? no->
-
- move.l pkey_shift,a0 ; yes: use shift table
- bra.s .ktab3 ; ->
-
- .ktab1: btst.l #NKFb_CAPS,d2 ; CapsLock?
- beq.s .ktab2 ; no->
-
- move.l pkey_caps,a0 ; yes: use CapsLock table
- bra.s .ktab3 ; ->
-
- .ktab2: move.l pkey_unshift,a0 ; use unshifted table
-
-
- *------------- check if scan code is out of range
- *
- * Illegal scancodes can be used to produce 'macro key codes'. Their format is:
- *
- * - the scancode must be $84 or larger (should be $ff to work properly with old
- * versions of Mag!x)
- * - the ASCII code must be in the range $20...$ff (values below are set to $20
- * by NKCC)
- * - Alternate and Control are not used for the normalized key code. However,
- * if at least one of them is non-zero, then the numeric keypad flag will be
- * set in the resulting key code.
- *
-
- .ktab3: cmp.b #$84,d1 ; illegal scan code?
- blo.s .ktab4 ; no ->
-
- move d2,d1 ; flags
- and #NKFf_ALT|NKFf_CTRL,d1 ; Alternate or Control?
- beq.s .special ; no ->
-
- or #NKFf_NUM,d0 ; yes: set numeric keypad flag
- and #NKFf_CAPS|NKFf_SHIFT,d2 ; mask off both flags
-
- .special: or d2,d0 ; combine with ASCII code
- or #NKFf_FUNC|NKFf_RESVD,d0 ; set function and resvd
- cmp.b #$20,d0 ; ASCII code in range?
- bhs .exit ; yes ->
-
- move.b #$20,d0 ; no: use minimum
- bra .exit ; ->
-
-
- *------------- check if Alternate + number: they have simulated scan codes
-
- .ktab4: cmp.b #$78,d1 ; scan code of Alt + number?
- blo.s .scan1 ; no->
-
- sub.b #$76,d1 ; yes: calculate REAL scan code
- move.b (a0,d1),d0 ; fetch ASCII code
- or #NKFf_ALT,d2 ; set Alternate flag
- bra .cat_codes ; -> add flag byte and exit
-
-
- *------------- check if exception scan code from cursor keypad
-
- .scan1: lea xscantab,a1 ; ^exception scan code table
-
- .search_scan: move (a1)+,d3 ; NKC and scan code
- bmi.s .tabend ; <0? end of table reached ->
-
- cmp.b d1,d3 ; scan code found?
- bne.s .search_scan ; no: continue search ->
-
- lsr #8,d3 ; .B = NKC
- moveq.l #0,d0 ; mark: key code found
- bra.s .scan2 ; ->
-
- .tabend: moveq.l #0,d3 ; no NKC found yet
-
-
- *------------- check if rubbish ASCII code and erase it, if so
-
- .scan2: move.b (a0,d1),d4 ; ASCII code from translation table
- cmp.b #32,d0 ; ASCII returned by TOS < 32?
- bhs.s .scan3 ; no -> can't be rubbish
-
- cmp.b d4,d0 ; yes: compare with table entry
- beq.s .scan3 ; equal: that's ok ->
-
- moveq.l #0,d0 ; not equal: rubbish! clear it
-
-
- *------------- check if ASCII code could only be produced via Alternate key
- * combination
-
- .scan3: tst.b d0 ; ASCII code valid?
- beq.s .scan4 ; no ->
-
- cmp.b d4,d0 ; compare with table entry
- beq.s .scan4 ; equal: normal key ->
-
- and #!NKFf_ALT,d2 ; no: clear Alternate flag
-
-
- *------------- check if ASCII code found yet, and set it, if not
-
- .scan4: tst.b d0 ; found?
- bne.s .scan5 ; yes ->
-
- move.b d3,d0 ; no: use code from exception table
- bne.s .scan5 ; now valid? yes ->
-
- move.b d4,d0 ; no: use code from transl. table
-
-
- *------------- check special case: delete key
-
- .scan5: cmp.b #127,d0 ; ASCII code of Delete?
- bne.s .scan6 ; no ->
-
- move.b #NK_DEL,d0 ; yes: set according NKC
-
-
- *------------- check if key is on numeric keypad (via scan code)
-
- .scan6: cmp.b #$4a,d1 ; numeric pad scan code range?
- beq.s .numeric ; yes ->
-
- cmp.b #$4e,d1
- beq.s .numeric ; yes ->
-
- cmp.b #$63,d1
- blo.s .scan7 ; no ->
-
- cmp.b #$72,d1
- bhi.s .scan7 ; no ->
-
- .numeric: or #NKFf_NUM,d2 ; yes: set numeric bit
-
-
- *------------- check if "function key" and set bit accordingly
-
- .scan7: cmp.b #32,d0 ; ASCII code less than 32?
- bhs.s .scan8 ; no ->
-
- or #NKFf_FUNC,d2 ; yes: set function bit
-
-
- *------------- check special case: Return or Enter key
-
- cmp.b #13,d0 ; Return or Enter key?
- bne.s .scan8 ; no ->
-
- btst.l #NKFb_NUM,d2 ; yes: from the numeric pad?
- beq.s .scan8 ; no -> it's Return, keep code
-
- moveq.l #NK_ENTER,d0 ; yes: it's Enter; new code
-
-
- *------------- check if function key (F1-F10) via scan code
-
- .scan8: cmp.b #$54,d1 ; shift + function key?
- blo.s .scan9 ; no ->
-
- cmp.b #$5d,d1
- bhi.s .scan9 ; no ->
-
- sub.b #$54-$3b,d1 ; yes: scan code for unshifted key
- move d2,d3 ; shift flags
- and #NKFf_SHIFT,d3 ; any shift key flag set?
- bne.s .scan9 ; yes ->
- or #NKFf_SHIFT,d2 ; no: set both flags
-
- .scan9: cmp.b #$3b,d1 ; (unshifted) function key?
- blo.s .cat_codes ; no ->
-
- cmp.b #$44,d1
- bhi.s .cat_codes ; no ->
-
- move.b d1,d0 ; yes: calc NKC
- sub.b #$2b,d0
-
-
- *------------- final flag handling; mix key code (low byte) and flag byte
-
- .cat_codes: move.l pkey_shift,a0 ; ^shifted table
- move.b (a0,d1),d3 ; get shifted ASCII code
- or d2,d0 ; mix flags with key code
- bmi.s .scan10 ; result is "function key"? ->
-
- and #NKFf_CTRL+NKFf_ALT,d2 ; Control or Alternate pressed?
- bne.s .scan11 ; yes ->
-
- .scan10: move.l pkey_unshift,a0 ; ^unshifted table
- cmp.b (a0,d1),d3 ; shifted ASCII = unshifted ASCII?
- beq.s .scan12 ; yes ->
-
- bra.s .exit ; no ->
-
- .scan11: or #NKFf_FUNC,d0 ; Alt/Ctrl + char: set function bit
- move.l pkey_caps,a0 ; ^CapsLock table
- cmp.b (a0,d1),d3 ; shifted ASCII = CapsLocked ASCII?
- bne.s .exit ; no ->
-
- move.b d3,d0 ; yes: use shifted ASCII code
-
- .scan12: or #NKFf_RESVD,d0 ; yes: nkc_cmp() has to check
- ; the Shift keys
-
- *------------- restore registers and exit
-
- .exit: tst d0 ; set CCR
- movem.l (sp)+,d3/d4 ; restore registers
- rts ; bye
-
-
- *------------- special handling for key codes created by TOS' 3.06 ASCII input
-
- .tos306: and #NKFf_CAPS,d2 ; isolate CapsLock flag
- or d2,d0 ; merge with ASCII code
- movem.l (sp)+,d3/d4 ; restore registers
- rts ; bye
-
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_gconv: GEM key code converter
- * # G R
- *
- * C prototype: int nkc_gconv(int gemkey);
- *---------------------------------------------------------------------------
- * Why a second key code converter, you ask? Well, in some cases it might
- * happen that the key status byte of the original key code (with states
- * of both Shift keys, Control, Alternate and CapsLock) is lost. Then
- * this converter function must be called, which uses another algorithm
- * to construct the normalized key code.
- *
- * Notes:
- * - the raw converter does no deadkey handling, ASCII input or Control
- * key emulation.
- * - NKCC does not use this function at all for its own purposes!
- * - some key combinations cannot be distinguished without the flag byte!
- * For example, "Alternate A" and "Shift Alternate A" produce the same
- * result. Whenever possible, use nkc_tconv()!
- *
- * In: D0.W key code in GEM format:
- * bits 15...08: scan code
- * bits 07...00: ASCII code
- *
- * Out: D0.W normalized key code (see nkc_tconv() for details)
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_gconv: movem.l d4-d7,-(sp) ; save registers
-
-
- *------------- find out "real" scan code and convert to TOS key code format
-
- move d0,d1 ; copy key code
- lsr #8,d1 ; scan code in d1.w
- swap d0 ; move key code to high word
- move.l pshift,a0 ; ^key state flags
- move.b (a0),d0 ; get 'em
- and #NKFf_CAPS>>8,d0 ; isolate CapsLock flag
- lea scan_trans,a0 ; ^scan code translation table
-
- .trans: move.l (a0)+,d2 ; get next entry
- beq.s .endtrans ; end of table? ->
-
- cmp.b d1,d2 ; scan code found?
- bne.s .trans ; no ->
-
- lsr #8,d2 ; "real" scan code
- move.b d2,d1 ; use it
- swap d2 ; flags to set
- or d2,d0 ; set them
-
- .endtrans: swap d0 ; move flags up and key code down
- moveq.l #0,d7 ; clear for word operation
- move.b d0,d7 ; copy ASCII code
- lsl.l #8,d0 ; shift flags and scan code up
- move d7,d0 ; restore ASCII code
-
-
- *------------- try to restore some of the key flags (shift/control/alternate)
-
- move.l pkey_unshift,a0 ; ^unshifted key table
- move.b (a0,d1),d4 ; get unshifted code
- move.l pkey_shift,a0 ; ^shifted key table
- move.b (a0,d1),d5 ; get shifted code
- move.l pkey_caps,a0 ; ^CapsLock key table
- move.b (a0,d1),d6 ; get CapsLock code
-
- bsr nk_ascmatch ; try to find ASCII code
- beq.s .conv ; found ->
-
- move.b #$1f,d2 ; maybe modified by Control key...
- and.b d2,d4 ; change ASCII code accordingly
- and.b d2,d5
- and.b d2,d6
- bsr nk_ascmatch ; and try again
- bne.s .notfnd ; no match ->
-
- .setctrl: or.l #(NKFf_FUNC|NKFf_CTRL)<<16,d0 ; Control was pressed
- bra.s .conv ; ->
-
- .notfnd: move.l pkey_unshift,a0 ; not found: restore all three
- move.b (a0,d1),d2 ; ASCII codes
- move.l pkey_shift,a0
- move.b (a0,d1),d5
- move.l pkey_caps,a0
- move.b (a0,d1),d6
- bsr.s .translate ; translate unshifted code
-
- move.b d2,d4 ; use translated code
- move.b d5,d2 ; translate shifted code
- bsr.s .translate
-
- move.b d2,d5 ; use translated code
- move.b d6,d2 ; translate shifted code
- bsr.s .translate
-
- move.b d2,d6 ; use translated code
- bsr nk_ascmatch ; last try to locate ASCII code
- beq.s .setctrl ; found ->
-
- tst.b d0 ; not found: ASCII code is 0?
- bne.s .conv ; no ->
-
- btst.l #NKFb_CTRL+16,d0 ; Control key flag already set?
- bne.s .conv ; yes ->
-
- ; no: must be Alternate
- or.l #(NKFf_FUNC|NKFf_ALT)<<16,d0
-
-
- *------------- do conversion to normalized format
-
- .conv: bsr nkc_tconv ; do TOS key code conversion
-
- movem.l (sp)+,d4-d7 ; restore registers
- tst d0 ; set CCR
- rts ; bye
-
-
- * This small sub function changes the ASCII code in D2.B due to the
- * ASCII code translation table asc_trans. The result is returned in D2.B,
- * registers D7 and A0 are corrupted.
-
- .translate: lea asc_trans,a0 ; ^translation table
-
- .transloop: move (a0)+,d7 ; get both codes
- beq.s .ret ; end of table? ->
-
- cmp.b d2,d7 ; found?
- bne.s .transloop ; no ->
-
- lsr #8,d7 ; yes: get translated code
- move.b d7,d2 ; and use it
-
- .ret: rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_n2tos: convert normalized key codes back to TOS format
- * # G R
- *
- * C prototype: long nkc_n2tos(int nkcode);
- *---------------------------------------------------------------------------
- * In some cases you might have to have key codes in the original TOS format
- * again, as returned by the GEMDOS functions Cconin(), Crawcin() or the BIOS
- * function Bconin(). Use nkc_n2tos() to convert them. For a detailed
- * description of the returned format consult the header of the function
- * nkc_tconv().
- *
- * In: D0.W key code in normalized format
- *
- * Out: D0.L key code in TOS format:
- * bits 24...31: shift key flags
- * bits 23...16: scan code
- * bits 08...15: reserved (0)
- * bits 00...07: ASCII code
- * CCR set according content of D0.L
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... =D0.L
- *
- ****************************************************************************
- *END
-
-
- nkc_n2tos: move d0,d1 ; normalized key code
- and #NKFf_FUNC|NKFf_ALT|NKFf_CTRL,d1 ; isolate flags
- cmp #NKFf_FUNC,d1 ; only function flag set?
- bne.s .ktab0 ; no ->
-
- cmp.b #$20,d0 ; ASCII code >= $20?
- blo.s .ktab0 ; no ->
-
-
- *------------- macro key
-
- move d0,d1 ; keep normalized key code
- and.l #NKFf_CAPS|NKFf_SHIFT,d0 ; isolate usable flags
- btst.l #NKFb_NUM,d1 ; numeric keypad flag set?
- beq.s .mackey ; no ->
-
- or #NKFf_ALT|NKFf_CTRL,d0 ; yes: set Alternate + Control
-
- .mackey: or.b #$ff,d0 ; scan code always $ff
- swap d0 ; flags and scan code in upper word
- move.b d1,d0 ; ASCII code
- bra .exit ; ->
-
-
- *------------- select system key table to use
-
- .ktab0: move d0,d1 ; normalized key code
- and #NKFf_SHIFT,d1 ; isolate bits for shift keys
- beq.s .ktab1 ; shift key pressed? no->
-
- lea n_to_scan_s,a1 ; ^default translation table
- move.l pkey_shift,a0 ; yes: use shift table
- bra.s .ktab3 ; ->
-
- .ktab1: lea n_to_scan_u,a1 ; ^unshifted translation table
- btst.l #NKFb_CAPS,d0 ; CapsLock?
- beq.s .ktab2 ; no->
-
- move.l pkey_caps,a0 ; yes: use CapsLock table
- bra.s .ktab3 ; ->
-
- .ktab2: move.l pkey_unshift,a0 ; use unshifted table
-
-
- *------------- handling for ASCII codes >= 32
-
- .ktab3: cmp.b #32,d0 ; ASCII code < 32?
- blo.s .lowascii ; yes ->
-
- bsr nk_findscan ; find scan code
- bne.s .found ; found ->
-
- btst.l #NKFb_FUNC,d0 ; function flag set?
- beq.s .notfound ; no ->
-
- move.l a0,d1 ; save a0
- lea tolower,a0 ; ^upper->lower case table
- moveq.l #0,d2 ; clear for word operation
- move.b d0,d2 ; ASCII code
- move.b (a0,d2),d0 ; get lowercased ASCII code
- move.l d1,a0 ; restore a0
- bsr nk_findscan ; try to find scan code again
- bne.s .found ; found ->
-
-
- *------------- unknown source: treat key code as it was entered using the
- * TOS 3.06 direct ASCII input
-
- .notfound: moveq.l #0,d1 ; not found: clear for word op.
- move.b d0,d1 ; unchanged ASCII code
- and #$1f00,d0 ; keep shift flags only
- swap d0 ; -> high word (scan code = 0)
- move d1,d0 ; low word: ASCII code
- bra .exit ; ->
-
-
- *------------- handling for ASCII codes < 32
-
- .lowascii: btst.l #NKFb_FUNC,d0 ; function key?
- bne.s .func ; yes ->
-
- and #$10ff,d0 ; clear all flags except CapsLock
- bra.s .notfound ; ->
-
- .func: moveq.l #0,d1 ; clear for word operation
- move.b d0,d1 ; ASCII code (0...$1f)
- move d1,d2 ; copy
- move.b (a1,d1),d1 ; get scan code
- bne.s .getascii ; valid? ->
-
- moveq #0,d0 ; invalid key code!! return 0
- bra .exit ; ->
-
- .getascii: lea n_to_scan_u,a1 ; ^unshifted translation table
- move.b (a1,d2),d2 ; get scan code from unshifted tab.
- move.b (a0,d2),d0 ; get ASCII from system's table
-
-
- * register contents:
- *
- * d0.b ASCII code
- * d1.b scan code
- * d0.hb NKCC flags
- *
-
- .found: move d0,d2 ; flags and ASCII code
- and #$1f00,d0 ; isolate shift flags
- move.b d1,d0 ; merge with scan code
- swap d0 ; -> high byte
- clr d0 ; erase low word
- move.b d2,d0 ; restore ASCII code
-
-
- *------------- handling for Control key flag
-
- btst.l #NKFb_CTRL,d2 ; control key flag set?
- beq.s .alternate ; no ->
-
- cmp.b #$4b,d1 ; scan code = "cursor left"?
- bne.s .scanchk2 ; no ->
-
- add.l #$280000,d0 ; change scan code to $73
- clr.b d0 ; erase ASCII code
- bra.s .exit ; ->
-
- .scanchk2: cmp.b #$4d,d1 ; scan code = "cursor right"?
- bne.s .scanchk3 ; no ->
-
- add.l #$270000,d0 ; change scan code to $74
- clr.b d0 ; erase ASCII code
- bra.s .exit ; ->
-
- .scanchk3: cmp.b #$47,d1 ; scan code = "ClrHome"?
- bne.s .ascchk ; no ->
-
- add.l #$300000,d0 ; change scan code to $77
- ; keep ASCII code in this case! What a mess...
- bra.s .exit ; ->
-
- .ascchk: lea asc_trans,a0 ; ^ASCII translation table
-
- .ascloop: move (a0)+,d1 ; get next entry
- beq.s .noctrlasc ; end of table ->
-
- cmp.b d0,d1 ; ASCII code found?
- bne.s .ascloop ; no -> continue search
-
- lsr #8,d1 ; yes: get translated code
- move.b d1,d0 ; use it
- bra.s .exit ; ->
-
- .noctrlasc: and.b #$1f,d0 ; mask off upper 3 bits
- bra.s .exit ; ->
-
-
- *------------- handling for Alternate key flag
-
- .alternate: btst.l #NKFb_ALT,d2 ; alternate key flag set?
- beq.s .exit ; no ->
-
- cmp.b #2,d1 ; top row on main keyboard?
- blo.s .alphachk ; no ->
-
- cmp.b #$d,d1
- bhi.s .alphachk ; no ->
-
- add.l #$760000,d0 ; yes: change scan code
- clr.b d0 ; and erase ASCII code
- bra.s .exit ; ->
-
- .alphachk: cmp.b #'A',d0 ; alpha-characters?
- blo.s .exit ; no ->
-
- cmp.b #'z',d0
- bhi.s .exit ; no ->
-
- cmp.b #'Z',d0
- bls.s .ascii0 ; yes ->
-
- cmp.b #'a',d0
- blo.s .exit ; no ->
-
- .ascii0: clr.b d0 ; alpha-character: clear ASCII code
-
- .exit: tst.l d0 ; set CCR
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_n2gem: convert normalized key codes back to GEM format
- * # G R
- *
- * C prototype: int nkc_n2gem(int nkcode);
- *---------------------------------------------------------------------------
- * Similar to nkc_n2tos(), this function converts normalized key codes back
- * to the operating system's format. The result is a key code as returned
- * by the AES functions evnt_keybd() respectively evnt_multi().
- *
- * In: D0.W key code in normalized format
- *
- * Out: D0.W key code in GEM format:
- * bits 08...15: scan code
- * bits 00...07: ASCII code
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_n2gem: bsr nkc_n2tos ; convert
- moveq.l #0,d1 ; clear for word operation
- move.b d0,d1 ; ASCII code
- ror.l #8,d0 ; scan code now in high byte
- move.b d1,d0 ; put ASCII into low byte
- tst d0 ; set CCR
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_kstate: return state of Shift/Control/Alternate/CapsLock in
- * normalized format
- * # G R
- *
- * C prototype: int nkc_kstate(void);
- *---------------------------------------------------------------------------
- * This is a very *FAST* function which returns the state of the Shift/
- * Control/Alternate and CapsLock keys in normalized format.
- *
- * In: -
- *
- * Out: D0.W normalized key flags:
- * 0 1
- * NKF?_CAPS no CapsLock CapsLock
- * NKF?_ALT no Alternate Alternate pressed
- * NKF?_CTRL no Control Control pressed
- * NKF?_LSH no left Shift key left Shift pressed
- * NKF?_RSH no right Shift key right Shift pressed
- *
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * w**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_kstate: move.l pshift,a0 ; ^shift state variable
- move.b (a0),d0 ; get its contents
- and #$1f,d0 ; isolate valid bits
- lsl #8,d0 ; make it NKC compatible
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_timer: return current value of 200 Hz system clock
- * # G R
- *
- * C prototype: unsigned long nkc_timer(void);
- *---------------------------------------------------------------------------
- * This is a very *FAST* function which returns the content of the 200 Hz
- * system clock.
- *
- * In: -
- *
- * Out: D0.L current 200 HZ system clock value
- *
- * Reg: D:01234567 A:01234567 CCR
- * w**..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_timer: move.l sysclock,d0 ; just get value
- rts ; bye bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_cmp: compare two key codes
- * # G R
- *
- * C prototype: int nkc_cmp(int refkey,int kcode);
- *---------------------------------------------------------------------------
- * nkc_cmp() compares key codes. What for, you ask? A simple "if key_code1
- * = key_code2" would also do it? No! This function follows some specific
- * rules, which improve the flexibility of key code comparism.
- *
- * One of the key codes passed to nkc_cmp() is called the "reference key
- * code". The other is the "test key code", which is got from nkc_conin()
- * or nkc_multi(). Some flags of the reference code are treated a special
- * way:
- *
- * NKF?_IGNUM (same as NKF?_RESVD)
- * if set, the numeric keypad flag doesn't matter
- *
- * NKF?_CAPS (CapsLock)
- * if set, the case of the ASCII code doesn't matter
- *
- * NKFf_SHIFT (both Shift key flags)
- * if BOTH shift flags are set, the combination of shift key flags in
- * the test key code doesn't matter: only one shift flag has to be set,
- * no matter which one.
- *
- * In: D0.W reference key code
- * D1.W key code to test
- *
- * Out: D0.W flag: 1 = key codes match
- * 0 = key codes don't match
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * u**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_cmp: movem.l d3-d4,-(sp) ; save registers
- move d0,d2 ; reference key code
- eor d1,d2 ; XORed with test key code
- beq .match ; identical: key codes match
-
- bmi.s .nomatch ; func flag differs -> don't match
-
- tst d0 ; "function" key?
- bmi.s .rfunc ; yes ->
-
-
- *------------- printable character
-
- btst.l #NKFb_IGNUM,d0 ; ignore numeric keypad flag?
- bne.s .chkn1 ; yes ->
-
- btst.l #NKFb_NUM,d2 ; numeric key flags equal?
- bne.s .nomatch ; no ->
-
- .chkn1: lea toupper,a0 ; ^upper case conversion table
- moveq.l #0,d3 ; clear for word operation
- move.b d0,d3 ; ASCII code of ref key code
- move.b (a0,d3),d4 ; get CapsLocked reference key code
-
- cmp.b d0,d1 ; ASCII code equal?
- beq.s .stest ; yes ->
-
- btst.l #NKFb_CAPS,d0 ; no: ignore case?
- beq.s .nomatch ; no -> codes don't match
-
- move.b d1,d3 ; ASCII of test key code
- cmp.b (a0,d3),d4 ; CapsLocked comparism
- beq.s .match ; equal ->
-
- bra.s .nomatch ; not equal ->
-
- .stest: btst.l #NKFb_RESVD,d1 ; check Shift keys?
- beq.s .match ; no ->
-
- .stest2: move #NKFf_SHIFT,d4 ; Shift key flags
- move d2,d3 ; XORed key codes
- and d4,d3 ; shift flags equal?
- beq.s .match ; yes ->
-
- move d0,d3 ; reference key code
- and d4,d3 ; isolate Shift flags
- cmp d3,d4 ; both set?
- bne.s .nomatch ; no -> codes don't match
-
- move d1,d3 ; check if any pressed in test code
- and d4,d3
- bne.s .match ; yes ->
-
- bra.s .nomatch ; no ->
-
-
- *------------- "function key"
-
- .rfunc: move d2,d3 ; XORed key codes
- and #NKFf_ALT|NKFf_CTRL,d3 ; check Alternate and Control
- bne.s .nomatch ; different -> codes don't match
-
- cmp.b #32,d0 ; special key or character?
- bhs.s .rchar ; character->
-
- cmp.b d0,d1 ; special key codes equal?
- beq.s .stest2 ; yes ->
-
- bra.s .nomatch ; no ->
-
- .rchar: btst.l #NKFb_IGNUM,d0 ; ignore numeric keypad flag?
- bne.s .chkn2 ; yes ->
-
- btst.l #NKFb_NUM,d2 ; numeric key flags equal?
- bne.s .nomatch ; no ->
-
- .chkn2: cmp.b d0,d1 ; ASCII codes equal?
- beq.s .stest ; yes ->
-
- .nomatch: movem.l (sp)+,d3-d4 ; restore registers
- moveq.l #0,d0 ; codes don't match
- rts ; bye
-
- .match: movem.l (sp)+,d3-d4 ; restore registers
- moveq.l #1,d0 ; codes match
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_vlink: link function to XBRA vector list
- * # G U
- *
- * C prototype: void nkc_vlink(long vector,int mode,void *pfnc);
- *---------------------------------------------------------------------------
- * This function can be used to change system vectors and let them point
- * to own functions, using a standard method. The vector, which should be
- * changed, is described by the contents of D0.L and D1.W. It can be
- * either a standard vector number, e.g. 2 for the bus error exception
- * vector, or the absolute address of the vector, e.g. $502 for the screen
- * dump vector. The function to install must have the following header:
- *
- * .dc.b "XBRA" magic longword
- * .dc.b "myID" four ASCII character ID of the function
- * (NKCC uses "NKCC", for example)
- * .dc.l 0 buffer for the old vector content
- * function: ... start of the function code
- *
- * The function should end with:
- *
- * move.l function-4(pc),-(sp)
- * rts
- *
- *
- * Note: in NKXM_ADR mode, this function automatically switches (temporary)
- * to Supervisor mode to prevent bus errors
- *
- *
- * In: D0.L vector descriptor
- * D1.W mode:
- * NKXM_NUM = D0.L contains a vector number
- * NKXM_ADR = D0.L contains a vector address
- * A0.L ^function to install (NOT ^XBRA header!)
- *
- * Out: -4(A0.L).L old content of vector
- *
- * Reg: D:01234567 A:01234567 CCR
- * ***..... **...... *
- *
- ****************************************************************************
- *END
-
-
- nkc_vlink: tst d1 ; which mode?
- bne.s .adr ; address ->
-
-
- *------------- install function by vector number
-
- move.l a2,-(sp) ; save register
-
- move.l a0,-(sp) ; ^function
- move d0,-(sp) ; vector number
- move #5,-(sp) ; Setexc
-
- moveq.l #-1,d1 ; ^function: don't change
- move.l d1,-(sp) ; vector
- move d0,-(sp) ; vector number
- move #5,-(sp) ; Setexc
-
- trap #13 ; BIOS: get old vector
- addq #8,sp ; clean stack
-
- move.l 4(sp),a0 ; ^function
- move.l d0,-4(a0) ; save old vector
- trap #13 ; BIOS: install routine
- addq #8,sp ; clean stack
-
- move.l (sp)+,a2 ; restore register
- rts ; bye
-
-
- *------------- install function by vector address
-
- .adr: movem.l a2-a4,-(sp) ; save registers
-
- move.l a0,a3 ; ^function
- move.l d0,a4 ; ^vector
-
- clr.l -(sp) ; use usp as ssp
- move #$20,-(sp) ; Super
- trap #1 ; GEMDOS
- move.l d0,2(sp) ; save old sp
- move #$20,(sp) ; Super opcode for next call
-
- move.l (a4),-4(a3) ; save old vector content
- move.l a3,(a4) ; install function
-
- trap #1 ; GEMDOS (back to User mode)
- addq #6,sp ; clean stack
-
- movem.l (sp)+,a2-a4 ; restore registers
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_vunlink: unlink function from XBRA vector list
- * # G U
- *
- * C prototype: int nkc_vunlink(long vector,int mode,void *pfnc);
- *---------------------------------------------------------------------------
- * nkc_vunlink() removes a function which was installed using the XBRA method.
- * For details see nkc_link(). If the XBRA list was corrupted, the function
- * aborts with an error code. This happens, when a non-XBRA routine is
- * installed on the same vector after the nkc_vlink() call of the function
- * to remove.
- *
- * Note: the function automatically switches (temporary) to Supervisor mode
- * to prevent bus errors
- *
- * In: D0.L vector descriptor
- * D1.W mode:
- * NKXM_NUM = D0.L contains a vector number
- * NKXM_ADR = D0.L contains a vector address
- * A0.L ^function to remove (NOT ^XBRA header!)
- *
- * Out: D0.W status:
- * 0 = OK
- * -1 = can't remove (XBRA list corrupted)
- * CCR set according content of D0.W
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... =D0.W
- *
- ****************************************************************************
- *END
-
- nkc_vunlink: movem.l d6-d7/a2/a6,-(sp) ; save registers
-
- move.l d0,d7 ; save vector descriptor
- move.l a0,a6 ; save function address
- move d1,d6 ; save mode
- bne.s .adr ; address mode ->
-
-
- *------------- check vector content by number
-
- moveq.l #-1,d0 ; get current vector
- move.l d0,-(sp)
- move d7,-(sp) ; vector number
- move #5,-(sp) ; Setexc
- trap #13 ; BIOS
- addq #8,sp ; clean stack
-
- cmp.l d0,a6 ; function still on top?
- bne.s .search ; no ->
-
- .restore: move.l -4(a6),-(sp) ; restore old vector
- move d7,-(sp) ; vector number
- move #5,-(sp) ; Setexc
- trap #13 ; BIOS
- addq #8,sp ; clean stack
- bra.s .okstat ; exit
-
-
- *------------- check vector content by address
-
- .adr: clr.l -(sp) ; use usp as ssp
- move #$20,-(sp) ; Super
- trap #1 ; GEMDOS
- move.l d0,2(sp) ; save old sp
- move #$20,(sp) ; Super opcode for next call
-
- move.l d7,a0 ; vector address
- move.l (a0),d0 ; vector content
- cmp.l d0,a6 ; function still on top?
- bne.s .search ; no ->
-
- move.l -4(a6),(a0) ; yes: remove it
- bra.s .okstat ; exit
-
-
- *------------- somebody installed a handler (hope he used XBRA ...)
-
- .search: move.l d0,a0 ; ^current handler
- move.l #'XBRA',d0 ; XBRA ID
-
- .find_hnd: cmp.l -12(a0),d0 ; XBRA ID before routine?
- bne.s .error ; no!!! can't remove function!!
-
- move.l -4(a0),a1 ; ^next entry in XBRA list
- cmp.l a1,a6 ; next entry in list our function?
- beq.s .found ; yes ->
-
- move.l a1,a0 ; no
- bra.s .find_hnd ; continue search
-
- .found: move.l -4(a6),-4(a0) ; yes: remove function
-
- .okstat: moveq.l #0,d7 ; no error
- bra.s .exit
-
- .error: moveq.l #-1,d7 ; error! can't unlink function!
-
- .exit: tst d6 ; address mode?
- beq.s .exit2 ; no ->
-
- trap #1 ; yes: switch to user mode first
- addq #6,sp ; with a GEMDOS Super() call
-
- .exit2: move d7,d0 ; status code
- movem.l (sp)+,d6-d7/a2/a6 ; restore registers
- rts ; bye
-
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_toupper: convert character to upper case
- * # G
- *
- * C prototype: unsigned char nkc_toupper(unsigned char chr);
- *---------------------------------------------------------------------------
- * A character is converted to upper case. Examples:
- *
- * 'a' -> 'A' (converted)
- * '/' -> '/' (unchanged; there's no upper case version for this)
- * 'A' -> 'A' (unchanged; already converted)
- *
- *
- * In: D0.B any character
- *
- * Out: D0.B character converted to upper case
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_toupper: lea toupper,a0 ; ^upper case translation table
- and #$ff,d0 ; high byte = 0 for word operation
- move.b (a0,d0),d0 ; convert
- rts ; bye
-
-
-
- *START
- ****************************************************************************
- *
- * nkc_tolower: convert character to lower case
- * # G
- *
- * C prototype: unsigned char nkc_tolower(unsigned char chr);
- *---------------------------------------------------------------------------
- * The counterpart of nkc_toupper(). A character is converted to lower case.
- *
- * In: D0.B any character
- *
- * Out: D0.B character converted to lower case
- *
- * Reg: D:01234567 A:01234567 CCR
- * U**..... **...... *
- *
- ****************************************************************************
- *END
-
- nkc_tolower: lea tolower,a0 ; ^lower case translation table
- and #$ff,d0 ; high byte = 0 for word operation
- move.b (a0,d0),d0 ; convert
- rts ; bye
-
-
-
- ****************************************************************************
- * LOCAL DATA SECTION *
- ****************************************************************************
-
- .data
-
- * exception scan code table for cursor block keys
- *
- * first entry.B: NKCC key code
- * second entry.B: scan code returned by TOS
- *
- * the table is terminated with both entries -1
-
- xscantab: .dc.b NK_UP , $48 ; cursor up
- .dc.b NK_DOWN , $50 ; cursor down
- .dc.b NK_LEFT , $4b ; cursor left
- .dc.b NK_LEFT , $73 ; Control cursor left
- .dc.b NK_RIGHT , $4d ; cursor right
- .dc.b NK_RIGHT , $74 ; Control cursor right
- .dc.b NK_M_PGUP , $49 ; Mac: page up
- .dc.b NK_M_PGDOWN , $51 ; Mac: page down
- .dc.b NK_M_END , $4f ; Mac: end
- .dc.b NK_INS , $52 ; Insert
- .dc.b NK_CLRHOME , $47 ; ClrHome
- .dc.b NK_CLRHOME , $77 ; Control ClrHome
- .dc.b NK_HELP , $62 ; Help
- .dc.b NK_UNDO , $61 ; Undo
- .dc.b NK_M_F11 , $45 ; Mac: F11
- .dc.b NK_M_F12 , $46 ; Mac: F12
- .dc.b NK_M_F14 , $37 ; Mac: F14
- .dc.w -1
-
-
-
- * deadkey table
- *
- * first entry.B: deadkey option mask (NKSf_D_...), 16 bits shifted down
- * second entry.W: ASCII code of deadkey
- * third entry.L: ^deadkey match table
- *
- * the table is terminated with an option mask of 0
-
- deadtab: .dc.w NKSf_D_CIRCUM >> 16
- .dc.b 0,'^'
- .dc.l d_circum
-
- .dc.w NKSf_D_TILDE >> 16
- .dc.b 0,'~'
- .dc.l d_tilde
-
- .dc.w NKSf_D_AGUI >> 16
- .dc.w $27
- .dc.l d_agui
-
- .dc.w NKSf_D_GRAVE >> 16
- .dc.b 0,'`'
- .dc.l d_grave
-
- .dc.w NKSf_D_UMLAUT >> 16
- .dc.b 0,'¨'
- .dc.l d_umlaut
-
- .dc.w NKSf_D_QUOTE >> 16
- .dc.w $22
- .dc.l d_umlaut
-
- .dc.w NKSf_D_SMOERE >> 16
- .dc.b 0,'°'
- .dc.l d_smoere
-
- .dc.w NKSf_D_CEDIL >> 16
- .dc.b 0,','
- .dc.l d_cedil
-
- .dc.w NKSf_D_SLASH >> 16
- .dc.b 0,'/'
- .dc.l d_slash
-
- .dc.w 0
-
-
-
- * deadkey match tables
- *
- * first entry.B: ASCII code generated by pressing deadkey and key code
- * second entry.B: key code (of the key which must be pressed directly after
- * the deadkey)
- *
- * the tables are terminated with both entries 0
-
- d_circum: .dc.b '^','^'
- .dc.b 'â','a'
- .dc.b 'ê','e'
- .dc.b 'î','i'
- .dc.b 'ô','o'
- .dc.b 'û','u'
- .dc.w 0
-
- d_tilde: .dc.b '~','~'
- .dc.b 'ñ','n'
- .dc.b 'Ñ','N'
- .dc.b 'ã','a'
- .dc.b 'õ','o'
- .dc.b 'Ã','A'
- .dc.b 'Õ','O'
- .dc.w 0
-
- d_agui: .dc.b $27,$27 ; ' characters
- .dc.b 'é','e'
- .dc.b 'É','E'
- .dc.b 'á','a'
- .dc.b 'í','i'
- .dc.b 'ó','o'
- .dc.b 'ú','u'
- .dc.w 0
-
- d_grave: .dc.b '`','`'
- .dc.b 'à','a'
- .dc.b 'è','e'
- .dc.b 'ì','i'
- .dc.b 'ò','o'
- .dc.b 'ù','u'
- .dc.b 'À','A'
- .dc.w 0
-
- d_umlaut: .dc.b '¨','¨'
- .dc.b $22,$22 ; " characters
- .dc.b 'ä','a'
- .dc.b 'ë','e'
- .dc.b 'ï','i'
- .dc.b 'ö','o'
- .dc.b 'ü','u'
- .dc.b 'ÿ','y'
- .dc.b 'Ä','A'
- .dc.b 'Ö','O'
- .dc.b 'Ü','U'
- .dc.w 0
-
- d_smoere: .dc.b '°','°'
- .dc.b 'å','a'
- .dc.b 'Å','A'
- .dc.w 0
-
- d_cedil: .dc.b ',',','
- .dc.b 'ç','c'
- .dc.b 'Ç','C'
- .dc.w 0
-
- d_slash: .dc.b '/','/'
- .dc.b 'ø','o'
- .dc.b 'Ø','O'
- .dc.b '½','2'
- .dc.b '¼','4'
- .dc.w 0
-
-
-
- .if NKCGEM=1
-
- * AES parameter block
-
- aespb: .dc.l nkc_contrl
- .dc.l 0 ; set by nkc_init()
- .dc.l nkc_intin
- .dc.l nkc_intout
- .dc.l nkc_adrin
- .dc.l nkc_adrout
-
- * VDI parameter block
-
- vdipb: .dc.l nkc_contrl
- .dc.l nkc_intin
- .dc.l nkc_ptsin
- .dc.l nkc_intout
- .dc.l nkc_ptsout
-
-
- * double click time table (values given in 1/200 s)
-
- timetab: .dc.l 85 ; 0.425 s
- .dc.l 63 ; 0.315 s
- .dc.l 49 ; 0.245 s
- .dc.l 42 ; 0.210 s
- .dc.l 30 ; 0.150 s
-
- .endif ; .if NKCGEM=1
-
-
-
- * lower case to upper case conversion table
- * (array of 256 unsigned bytes)
-
- toupper:
- .dc.b $00,$01,$02,$03,$04,$05,$06,$07
- .dc.b $08,$09,$0a,$0b,$0c,$0d,$0e,$0f
- .dc.b $10,$11,$12,$13,$14,$15,$16,$17
- .dc.b $18,$19,$1a,$1b,$1c,$1d,$1e,$1f
- .dc.b " !",$22,"#$%&",$27,"()*+,-./0123456789:;<=>?"
- .dc.b "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[",$5c,"]^_"
- .dc.b "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~"
- .dc.b "ÇÜÉâÄÀÅÇêëèïîìÄÅÉÆÆôÖòûùÿÖÜ¢£¥ßƒ"
- .dc.b "áíóúÑѪº¿⌐¬½¼¡«»ÃÕØØŒŒÀÃÕ¨´†¶©®™"
- .dc.b "ijIJאבגדהוזחטיכלמנסעפצקרשתןךםףץ§∧∞"
- .dc.b "αβΓπΣσµτΦΘΩδ∮ϕ∈∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²³¯"
-
-
- * upper case to lower case conversion table
- * (array of 256 unsigned bytes)
-
- tolower:
- .dc.b $00,$01,$02,$03,$04,$05,$06,$07
- .dc.b $08,$09,$0a,$0b,$0c,$0d,$0e,$0f
- .dc.b $10,$11,$12,$13,$14,$15,$16,$17
- .dc.b $18,$19,$1a,$1b,$1c,$1d,$1e,$1f
- .dc.b " !",$22,"#$%&",$27,"()*+,-./0123456789:;<=>?"
- .dc.b "@abcdefghijklmnopqrstuvwxyz[",$5c,"]^_"
- .dc.b "`abcdefghijklmnopqrstuvwxyz{|}~"
- .dc.b "çüéâäàåçêëèïîìäåéææôöòûùÿöü¢£¥ßƒ"
- .dc.b "áíóúññªº¿⌐¬½¼¡«»ãõøøœœàãõ¨´†¶©®™"
- .dc.b "ijIJאבגדהוזחטיכלמנסעפצקרשתןךםףץ§∧∞"
- .dc.b "αβΓπΣσµτΦΘΩδ∮ϕ∈∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²³¯"
-
- * note for both tables:
- *
- * $22 = " character
- * $27 = ' character
- * $5c = \ character
-
-
- * scan code translation table
- *
- * first entry.W : shift flags (NKFf_CTRL/SHIFT/ALT/FUNC), 8 bits shifted down
- * second entry.B: real scan code (index into key table)
- * third entry.B : simulated scan code (set by OS when the flags specified
- * above are set)
- *
- * The table is terminated with all entries 0.
-
- scan_trans: .dc.w NKFf_SHIFT>>8 ; Shift F1
- .dc.b $3b,$54
- .dc.w NKFf_SHIFT>>8 ; Shift F2
- .dc.b $3c,$55
- .dc.w NKFf_SHIFT>>8 ; Shift F3
- .dc.b $3d,$56
- .dc.w NKFf_SHIFT>>8 ; Shift F4
- .dc.b $3e,$57
- .dc.w NKFf_SHIFT>>8 ; Shift F5
- .dc.b $3f,$58
- .dc.w NKFf_SHIFT>>8 ; Shift F6
- .dc.b $40,$59
- .dc.w NKFf_SHIFT>>8 ; Shift F7
- .dc.b $41,$5a
- .dc.w NKFf_SHIFT>>8 ; Shift F8
- .dc.b $42,$5b
- .dc.w NKFf_SHIFT>>8 ; Shift F9
- .dc.b $43,$5c
- .dc.w NKFf_SHIFT>>8 ; Shift F10
- .dc.b $44,$5d
- .dc.w (NKFf_FUNC|NKFf_CTRL)>>8 ; Control cursor left
- .dc.b $4b,$73
- .dc.w (NKFf_FUNC|NKFf_CTRL)>>8 ; Control cursor right
- .dc.b $4d,$74
- .dc.w (NKFf_FUNC|NKFf_CTRL)>>8 ; Control ClrHome
- .dc.b $47,$77
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #1
- .dc.b $02,$78
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #2
- .dc.b $03,$79
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #3
- .dc.b $04,$7a
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #4
- .dc.b $05,$7b
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #5
- .dc.b $06,$7c
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #6
- .dc.b $07,$7d
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #7
- .dc.b $08,$7e
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #8
- .dc.b $09,$7f
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #9
- .dc.b $0a,$80
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #10
- .dc.b $0b,$81
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #11
- .dc.b $0c,$82
- .dc.w (NKFf_FUNC|NKFf_ALT)>>8 ; Alternate top row #12
- .dc.b $0d,$83
- .dc.l 0 ; terminator
-
-
- * ASCII code translation table for Control key
- *
- * first entry.B: modified ASCII code returned by TOS
- * second entry.B: original ASCII code as stored in key table
- *
- * The table is terminated with both entries 0
-
- asc_trans: .dc.b 0,'2' ; Control '2' becomes ASCII 0
- .dc.b $1e,'6' ; Control '6' becomes ASCII $1e
- .dc.b $1f,'-' ; Control '-' becomes ASCII $1f
- .dc.b $a,$d ; Control Return/Enter: $d -> $a
- .dc.w 0 ; terminator
-
-
- * normalized key code -> scan code translation table
- * for unshifted key codes
- * indexed by function code (NK_...)
-
- n_to_scan_u: .dc.b $00 ; invalid key code
- .dc.b $48 ; cursor up
- .dc.b $50 ; cursor down
- .dc.b $4d ; cursor right
- .dc.b $4b ; cursor left
- .dc.b $49 ; Mac: page up
- .dc.b $51 ; Mac: page down
- .dc.b $4f ; Mac: end
- .dc.b $0e ; Backspace
- .dc.b $0f ; Tab
- .dc.b $72 ; Enter
- .dc.b $52 ; Insert
- .dc.b $47 ; ClrHome
- .dc.b $1c ; Return
- .dc.b $62 ; Help
- .dc.b $61 ; Undo
- .dc.b $3b ; function key #1
- .dc.b $3c ; function key #2
- .dc.b $3d ; function key #3
- .dc.b $3e ; function key #4
- .dc.b $3f ; function key #5
- .dc.b $40 ; function key #6
- .dc.b $41 ; function key #7
- .dc.b $42 ; function key #8
- .dc.b $43 ; function key #9
- .dc.b $44 ; function key #10
- .dc.b $45 ; Mac: F11
- .dc.b $01 ; Esc
- .dc.b $46 ; Mac: F12
- .dc.b $37 ; Mac: F14
- .dc.b $00 ; reserved!
- .dc.b $53 ; Delete
-
- * normalized key code -> scan code translation table
- * for shifted key codes
- * indexed by function code (NK_...)
-
- n_to_scan_s: .dc.b $00 ; invalid key code
- .dc.b $48 ; cursor up
- .dc.b $50 ; cursor down
- .dc.b $4d ; cursor right
- .dc.b $4b ; cursor left
- .dc.b $49 ; Mac: page up
- .dc.b $51 ; Mac: page down
- .dc.b $4f ; Mac: end
- .dc.b $0e ; Backspace
- .dc.b $0f ; Tab
- .dc.b $72 ; Enter
- .dc.b $52 ; Insert
- .dc.b $47 ; ClrHome
- .dc.b $1c ; Return
- .dc.b $62 ; Help
- .dc.b $61 ; Undo
- .dc.b $54 ; function key #1
- .dc.b $55 ; function key #2
- .dc.b $56 ; function key #3
- .dc.b $57 ; function key #4
- .dc.b $58 ; function key #5
- .dc.b $59 ; function key #6
- .dc.b $5a ; function key #7
- .dc.b $5b ; function key #8
- .dc.b $5c ; function key #9
- .dc.b $5d ; function key #10
- .dc.b $45 ; Mac: F11
- .dc.b $01 ; Esc
- .dc.b $46 ; Mac: F12
- .dc.b $37 ; Mac: F14
- .dc.b $00 ; reserved!
- .dc.b $53 ; Delete
-
-
-
- ****************************************************************************
- * LOCAL BSS SECTION *
- ****************************************************************************
-
- .bss
-
-
- * key code handler
-
- pkey_unshift: .ds.l 1 ; ^unshifted key table
- pkey_shift: .ds.l 1 ; ^shifted key table
- pkey_caps: .ds.l 1 ; ^CapsLock table
- pshift: .ds.l 1 ; ^shift state system variable
- sflags: .ds.l 1 ; special key flags
- prvkey: .ds.w 1 ; previous key code
- prvvalid: .ds.b 1 ; non-zero: prvkey is valid
- .even
-
-
- * button event handler
-
- .if NKCGEM=1
-
- bvar: .ds.b BI ; button event info block
- tendtime: .ds.l 1 ; timer event end value
- prvtime: .ds.l 1 ; previous timer event value
- vdihnd: .ds.w 1 ; handle of VDI workstation
- multibuf: .ds.w 16+2 ; buffer for evnt_multi parameters
- buthnd: .ds.b 1 ; non-zero:button handler installed
- .even
-
-
-
- * other stuff
-
- kbdiorec: .ds.l 1 ; ^keyboard Iorec structure
- iohead: .ds.w 1 ; NKCC's head pointer
-
- .endif ; .if NKCGEM=1
-
- sysclock: .ds.l 1 ; copy of 200 Hz system clock
- timerflag: .ds.b 1 ; non-zero:200 Hz timer installed
- .even
-
-
-
- *START
- ****************************************************************************
- * GLOBAL BSS SECTION *
- ****************************************************************************
- *END
-
- .bss
-
- *START
- * GEM parameter arrays
- * (needed if using nkc_amulti())
-
- .if NKCGEM=1
-
- nkc_contrl: .ds.w 32 ; control array
- nkc_intin: .ds.w 32 ; integer input array
- nkc_intout: .ds.w 32 ; integer output array
- nkc_adrin: .ds.l 32 ; address input array
- nkc_adrout: .ds.l 32 ; address output array
- nkc_ptsin: .ds.l 32 ; pointers input array
- nkc_ptsout: .ds.l 32 ; pointers output array
-
- .endif ; .if NKCGEM=1
- *END
-
- *START
- * End Of File
- *END
-
-